javascript - s3 "signature doesn't match" client side post jquery-file-upload -


i generating signature doing client side posting s3 in node on end , submitting via jquery-file-upload on client. signature generation looks following:

  app.post('/api/v1/s3', function(req, res){     var data = utils.getreqjson(req.body);     var mime_type = mime.lookup(data.filename);     var expire = moment().utc().add('hour', 1).tojson("yyyy-mm-ddthh:mm:ss z");     var policy = json.stringify({       "expiration": expire,       "conditions": [          {"bucket": aws_bucket},         ["starts-with", "$key", aws_bucket_dir],         {"acl": "private"},         {"success_action_status": "201"},         ["starts-with", "$content-type", ''],         ["content-length-range", 0, max_filesize]       ]     });     var base64policy = new buffer(policy).tostring('base64');     var signature = crypto.createhmac('sha1', process.env.aws_secret).update(base64policy).digest('base64');     signature = encodeuricomponent(signature.trim());     signature = signature.replace('%2b','+');     var file_key = uuid.v4();     res.json({ policy: base64policy,       signature: signature,       key: aws_bucket_dir + file_key + "_" + data.filename,       contenttype: mime_type,       aws_access: process.env.aws_access_key,       bucket_dir: aws_bucket_dir,       bucket: aws_bucket     });   }); 

then on front end have following code:

this.$().fileupload({   datatype: 'json',   type: 'post',   autoupload: true,   add: function (e, data) {     $.ajax({       url: window.env.api_url+'/' + window.env.api_namespace + '/s3',       type: 'post',       datatype: 'json',       data: {         "filename": data.files[0].name       },       async: false,       success: function(retdata) {         //do actual upload stuff now.         data.url = 'https://'+retdata.bucket+'.s3.amazonaws.com/';         data.formdata = {           key: retdata.key,           awsaccesskeyid: retdata.aws_access,           acl: 'private',           policy: retdata.policy,           signature: retdata.signature,           success_action_status: 201,           "content-type": retdata.contenttype          };         data.submit()           .success(function (result, textstatus, jqxhr) {             console.log('success: ' + result);           })           .error(function (jqxhr, textstatus, errorthrown) {             console.log('error: ' + errorthrown);             console.log(jqxhr);             console.log('status: ' + textstatus);                           });         console.log(retdata);       },       error: function (xhr, ajaxoptions, thrownerror) {         console.log('ajax: ' + xhr);         console.log('ajax: ' + thrownerror);       }     });   },   progressall: function (e, data) {     var progress = parseint(data.loaded / data.total * 100, 10);     $('#progress .progress-bar').css(       'width',       progress + '%'     );   } }); 

it seems though submitting correct form data match signature generation, getting following errors every time try submit:

signaturedoesnotmatch - request signature calculated not match signature provided. check key , signing method.

i struggling figure out might doing wrong, if can appreciate it.

i struggled while , got working using following:

in s3 handler:

var uploadtos3 = function(s3url, cb){   var fd = new formdata();   var file = document.getelementbyid('file').files[0];   var key = 'uploads\/' + file.name;    fd.append('key', 'uploads\/' + file.name);   fd.append('acl', 'public-read');   fd.append('content-type', 'multipart/form-data');   fd.append('awsaccesskeyid', 'xxxx');   fd.append('policy', s3url.s3policy);   fd.append('signature', s3url.s3signature);   fd.append('file', file);    var xhr = new xmlhttprequest();   xhr.open('post', 'https://xxxx.s3.amazonaws.com', true);    /////////////////////////////////////////////////////////   // keep track of upload progress can message//   // user.                                     //   /////////////////////////////////////////////////////////    var firstprogressevent = true;   xhr.loaded = 0;   xhr.upload.addeventlistener('progress', function(e) {     if (firstprogressevent) {       firstprogressevent = false;     }     xhr.loaded += (e.loaded - xhr.loaded);     $('progress').val((xhr.loaded / e.total) * 100);   }, false);    xhr.onreadystatechange = function(){      if ( xhr.readystate == 4 ) {        if ( xhr.status >= 200 && xhr.status < 400 ) {          cb(xhr.status);       } else {          cb(xhr.status);       }      }    };    xhr.onerror = function () {      error(xhr, xhr.status);    };    xhr.send(fd); }; 

});

on server:

creates3policy = function(key, callback) {   var date = new date();   var s3policy = {     "expiration": new date(date.now() + 300000),     "conditions": [       {"bucket": "xxx"},        ["starts-with", "$key", key],        {"acl": "public-read"},       ["starts-with", "$content-type", "multipart/form-data"],       ["content-length-range", 0, 524288000]     ]   };    ////////////////////////////////////   // stringify , encode policy//   ////////////////////////////////////   var stringpolicy = json.stringify(s3policy);   var base64policy = buffer(stringpolicy, "utf8").tostring("base64");    ////////////////////////////////////   // sign base64 encoded policy //   ////////////////////////////////////   var signature = crypto.createhmac("sha1", process.env.aws_secret_access_key)     .update(new buffer(base64policy, "utf8")).digest("base64");    ////////////////////////////////////   // build results object       //   ////////////////////////////////////   var s3credentials = {     s3policy: base64policy,     s3signature: signature   };      callback(s3credentials); }; 

Comments

Popular posts from this blog

javascript - jquery or ashx not working -

opencv - DataType<cv::detail::deriv_type>::depth what is it used for -

python 3.x - Mapping specific letters onto a list of words -