-
-
Save mmoehrlein/c1d9a8500ecc6fd10ab00c2ef2971740 to your computer and use it in GitHub Desktop.
<?php | |
// AWS data | |
$bucketName = "BUCKET-NAME"; | |
$AWSAccessKeyId = "XXXXXXXXXXXXXXXXXXXX"; | |
$AWSSecretAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; | |
$date = date("Y-m-d"); | |
$dateISO = date("Ymd"); | |
$validTill = date('Y-m-d\TH:i:s.000\Z', time() + (60 * 60 * 4)); // 4 hours | |
$alg = "sha256"; | |
$region = "REGION"; | |
$service = "s3"; | |
// syntax: hash_hmac(algorithm, string, key, binaryOutput) | |
$kSecret = 'AWS4' . $AWSSecretAccessKey; | |
$kDate = hash_hmac($alg, $dateISO, $kSecret, true); | |
$kRegion = hash_hmac($alg, $region, $kDate, true); | |
$kService = hash_hmac($alg, $service, $kRegion, true); | |
$secretSignatureKey = hash_hmac($alg, 'aws4_request', $kService, true); | |
// user specific data | |
$IdOne = "1"; | |
$IdTwo = "1234"; | |
$keyPrefix = "new/" . $IdOne . "/" . $IdTwo . "/" . date("Y-m-d_H-i-s_"); | |
$keyFilename = '${filename}'; | |
// fields to be used within form | |
$url = "https://" . $bucketName . ".s3.amazonaws.com/"; | |
$key = $keyPrefix . $keyFilename; | |
$acl = "private"; | |
$success_action_redirect = ""; | |
$ContentType = "image/jpeg"; // can be empty, if there shouldn't be any restrictions | |
$amzMetaTag = ""; // optional tags | |
$maxFilesize = 1048576; // 1 MB | |
$policy = '{ | |
"expiration": "' . $validTill . '", | |
"conditions": [ | |
{"bucket": "' . $bucketName . '"}, | |
["starts-with", "$key", "' . $keyPrefix . '"], | |
{"acl": "' . $acl . '"}, | |
{"success_action_redirect": "' . $success_action_redirect . '"}, | |
["starts-with", "$Content-Type", "' . $ContentType . '"], | |
["content-length-range", 0, ' . $maxFilesize . '], | |
{"x-amz-server-side-encryption": "AES256"}, | |
["starts-with", "$x-amz-meta-tag", "' . $amzMetaTag . '"], | |
{"x-amz-credential": "' . $AWSAccessKeyId . '/' . $dateISO . '/us-east-2/s3/aws4_request"}, | |
{"x-amz-algorithm": "AWS4-HMAC-SHA256"}, | |
{"x-amz-date": "' . $dateISO . 'T000000Z" } | |
] | |
}'; | |
$policyBase64 = base64_encode($policy); | |
$signature = hash_hmac($alg, $policyBase64, $secretSignatureKey); | |
?> | |
<html> | |
<head> | |
<title>S3 Dropzone</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css"> | |
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script> | |
</head> | |
<body> | |
<br><br><br> | |
<h1 style="text-align: center">ImageUpload to "<?=$bucketName?>" - S3Bucket</h1> | |
<div id="test" class="dropzone dz-clickable"></div> | |
<script type="text/javascript"> | |
Dropzone.options.test = { | |
url: "<?= $url ?>", | |
method: "post", | |
uploadMultiple: false, | |
sending: function (file, xhr, data) { | |
data.append("key", "<?= $key ?>"); | |
data.append("acl", "<?= $acl ?>"); | |
data.append("success_action_redirect", "<?= $success_action_redirect ?>"); | |
data.append("Content-Type", "<?= $ContentType ?>"); | |
data.append("x-amz-server-side-encryption", "AES256"); | |
data.append("X-Amz-Credential", "<?= $AWSAccessKeyId ?>/<?= $dateISO ?>/us-east-2/s3/aws4_request"); | |
data.append("X-Amz-Algorithm", "AWS4-HMAC-SHA256"); | |
data.append("X-Amz-Date", "<?= $dateISO ?>T000000Z"); | |
data.append("x-amz-meta-tag", ""); | |
data.append("X-Amz-Signature", "<?= $signature ?>"); | |
data.append("Policy", "<?= $policyBase64 ?>"); | |
} | |
}; | |
</script> | |
</body> | |
</html> |
I'm getting a 403 trying this. I've verified via a php app that the IAM settings work fine. I generated a key/secret and added them to the script. I have been using the same us-east-2 in my other tests. I even tried changing the acl setting with no luck.
@treii28 did you solve it?
I'm using a different method in the browser with aws-sdk and retrieving a signed upload url via the sdk multipart upload. But now I'm running into another problem where if I add more than 10 or so files to the process queue, not all of them finish.
Wow, that help really a lot! Thank you!
There are 2 small bugs, if you fix them, it will be perfect. You use 2 time hard-coded region "us-east-2". that doesn't work for everyone.
One more hint for the newcomers, open your S3 permissions tab and put that code peace under CORS section:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"POST",
"PUT",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
@mmoehrlein @serdarde
Thank you very much
Hi This is amazing !! This what I was looking for !!
I am using an alternate S3 ( cheaper than aws ... ) provider. I tried to change some parameters ( Bucket AWSAccessKeyId, AWSSecretAccessKey ) but it did not work, any idea ? the aws4 signature maybe ?