-
-
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 ?