S3"签名不匹配"客户端后jQuery的文件上传 [英] s3 "signature doesn't match" client side post jquery-file-upload

查看:136
本文介绍了S3"签名不匹配"客户端后jQuery的文件上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我生成做客户端张贴在在后端节点S3和经由在客户端上的jquery-文件上传提交它的签名。我的签名生成类似如下:

I am generating a signature for doing client side posting to s3 in node on the back end and submitting it via jquery-file-upload on the client. My signature generation looks like the 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
    });
  });

然后在前端,我有以下code:

Then on the front end I have the 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 as though I am submitting the correct form data to match my signature generation, but I am getting the following errors every time I try to submit:

SignatureDoesNotMatch - 我们计算没有您提供的签名和请求签名。检查你的密钥和签名方法。

我在努力找出我可能是做错了,如果有人可以帮助我将AP preciate吧。

I am struggling to figure out what I might be doing wrong, if anyone can help I would appreciate it.

推荐答案

我这个挣扎了一会儿,最终得到了它的工作使用了以下内容:

I struggled with this for a while and eventually got it working using the following:

在S3处理程序:

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 so that we can message//
  // it to the 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);
};

});

在服务器上:

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 and encode the policy//
  ////////////////////////////////////
  var stringPolicy = JSON.stringify(s3Policy);
  var base64Policy = Buffer(stringPolicy, "utf8").toString("base64");

  ////////////////////////////////////
  // sign the base64 encoded policy //
  ////////////////////////////////////
  var signature = crypto.createHmac("sha1", process.env.AWS_SECRET_ACCESS_KEY)
    .update(new Buffer(base64Policy, "utf8")).digest("base64");

  ////////////////////////////////////
  // build the results object       //
  ////////////////////////////////////
  var s3Credentials = {
    s3Policy: base64Policy,
    s3Signature: signature
  };

    callback(s3Credentials);
};

这篇关于S3&QUOT;签名不匹配&QUOT;客户端后jQuery的文件上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆