I know many asked this question and I looked into their post but I still never got the correct answer so here goes.
I'm trying to upload an image to s3 using the Browser Based uploading technique introduce by Amazon dev. Right now I'm able to calculate both policy & signature on my end. But when I tried to upload an image I always get a "Signature not match" (>.<). One main problem I'm having is that the credentials I have are just temporary: AWS Security Token Service, this consist of an accessKEy, secretKey and security token. I'll post my code so anyone please
Here's my policy_json conversion
function setValues(accesskey, secretkey, token) {
var folder = 'avatars/email@domain.com/',
acl = 'public-read',
bucket = 'my-bucket';
var POLICY_JSON = { "expiration": "2013-12-03T12:29:27.000Z",
"conditions": [
{"bucket": bucket},
["starts-with", "$key", folder],
{"acl": acl},
{"success_action_redirect": "201"},
["starts-with", "$Content-Type", "image/png"]
]
};
var policy = Base64.encode(JSON.stringify(POLICY_JSON));
var signature = b64_hmac_sha1(secretkey, policy);
return {
"policy":policy,
"signature":signature,
"folder" : folder,
"acl" : acl,
"bucket" : bucket
}
}
My upload
function upload(acl, accesskey, policy, signature, token) {
$(':button').click(function()
{
var file = document.getElementById('file').files[0];
// var key = "events/" + (new Date).getTime() + '-' + file.name;
var xdate = '20131016T105000Z';
// var formData = new FormData($('form')[0]); //$('form')[0]
var formData = new FormData(); //$('form')[0]
formData.append("key", "avatars/email@domain.com/${filename}");
formData.append("acl", acl);
formData.append("success_action_redirect", "201");
formData.append("Content-Type", file.type);
formData.append("AWSAccessKeyId", accesskey);
formData.append("policy", policy);
formData.append("signature", signature);
// formData.append("x-amz-security-token", token);
formData.append("file", file);
$.ajax({
url: 'https://mybucket.s3.amazonaws.com', //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // Check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
beforeSend: function(e) {
e.setRequestHeader("Authorization", "AWS "+accesskey+":"+signature);
e.setRequestHeader("x-amz-date", xdate);
e.setRequestHeader("x-amz-acl", acl);
e.setRequestHeader("x-amz-security-token", token);
// alert('Are you sure you want to upload document.');
},
success: function(e) { alert('Upload completed'); } ,
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(errorThrown);
} ,
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
}
My only html
<form enctype="multipart/form-data">
<input id="file" name="file" type="file" />
<input type="button" value="Upload" />
</form>
This is what confused me, at first inside the mybucket it has a folder named avatars now when my colleague uploaded an image (say image1.jpg)
using his email_address (say other_email_Address@domain.com)
and the uploading is successful when we look at the bucket it created a folder with the name of his email_address and inside it the image. Why is that?
mybucket/
- avatars/
- my_email_address.@domain.com
- image1
- other_email_address@domain.com
- image1
so on ...
the tools i used are: webtoolkit.base64.js, sha1.js, base64-binary.js.