Heroku NodeJS:使用aws-sdk错误SignatureDoesNotMatch

时间:2016-06-12 11:19:54

标签: angularjs node.js amazon-web-services heroku amazon-s3

节点:5.6.0 角度:1.4.5 风帆:0.12.1

我正在使用SailsJS和Angular构建应用程序,我需要将图像上传到S3,但是在运行PUT http请求时我一直收到SignatureDoesNotMatch错误。

我遵循了这个heroku guide但显然我不得不使用角度和风帆而不是香草js并表达。

我经常搜索,但找不到真正有用的东西。 示例:https://github.com/aws/aws-sdk-js/issues/86

我不知道我做错了什么。

这是代码: AwsController:

var aws = require('aws-sdk');

module.exports = {
  "sign-s3": function(req, res) {
    const s3 = new aws.S3({region: 'eu-west-1'});
    const fileName = req.param('file-name');
    const fileType = req.param('file-type');
    const s3Params = {
      Bucket: process.env.S3_BUCKET,
      Key: fileName,
      Expires: 60,
      ContentType: fileType,
      ACL: 'public-read'
    };

    s3.getSignedUrl('putObject', s3Params, function (err, data) {
      if(err){
        console.log(err);
        return res.end();
      }

      const returnData = {
        signedRequest: data,
        url: 'https://' + process.env.S3_BUCKET + '.s3.amazonaws.com/' + fileName
      };

      return res.json(returnData);
    });
  }
};

app.factory.aws-manager.js:

function getSignedRequest(file) {
  return $http.get('/aws/sign-s3?file-name=' + file.name + '&file-type=' + file.type)
    .then(successCallback)
    .catch(errorCallback);

  function successCallback(response) {
    return response.data;
  }

  function errorCallback(response) {
    console.log(response);
    return response;
  }
}

function sendFile(file, signedRequest, url){
  var data = {file: file};

  return $http.put(signedRequest, data)
    .then(successCallback)
    .catch(errorCallback);

  function successCallback(response) {
    return { data: response.data, url: url};
  }

  function errorCallback(response) {
    console.log(response);
    return response;
  }
}

function uploadFile(file) {
  return getSignedRequest(file)
    .then(successCallback);

  function successCallback(data) {
    console.log(data);
    return sendFile(file, data.signedRequest, data.url)
      .then(successCallback);

    function successCallback(response) {
      return response.url;
    }
  }
}

电话:

awsManager.uploadFile(file);

错误:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
    <AWSAccessKeyId>AKIAJFI5FDWJK7TTGIKQ</AWSAccessKeyId>
    <StringToSign>PUT application/json;charset=UTF-8 1465728343 x-amz-acl:public-read /aemporium-assets/einstein.jpg</StringToSign>
    <SignatureProvided>mtVl69xyqhAbYhQt1oZk0F1w1WE=</SignatureProvided>
    <StringToSignBytes>50 55 54 0a 0a 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e 3b 63 68 61 72 73 65 74 3d 55 54 46 2d 38 0a 31 34 36 35 37 32 38 33 34 33 0a 78 2d 61 6d 7a 2d 61 63 6c 3a 70 75 62 6c 69 63 2d 72 65 61 64 0a 2f 61 65 6d 70 6f 72 69 75 6d 2d 61 73 73 65 74 73 2f 65 69 6e 73 74 65 69 6e 2e 6a 70 67</StringToSignBytes>
    <RequestId>900A623A516D2DDD</RequestId>
<HostId>j1t+w1N6MLeWA2UAirQbTXIa2+U5vVtMTSYiRo72SzOnzDf0TyDZxlL4VoXnCLqXu+hv/rxN9Z8=</HostId>
</Error>

(我确定所有process.env。*变量都是正确的)

1 个答案:

答案 0 :(得分:0)

我发现了问题,我没注意到在PUT调用的请求标头中我有2个错误的参数:

  1. 接受:是json / application,必须是* / *

  2. Content-Type:它是json / application,必须是“file.type”

  3. 更正的代码:

    function sendFile(file, signedRequest, url){
      var data = {file: file};
    
      return $http.put(signedRequest, file, {"headers": {"Accept":"*/*", "Content-Type":file.type}})
        .then(successCallback)
        .catch(errorCallback);
    
      function successCallback(response) {
        return { data: response.data, url: url};
      }
    
      function errorCallback(response) {
        console.log(response);
        return response;
      }
    }