JavaScript使用预先签名的URL保存到S3

时间:2018-02-22 23:16:07

标签: amazon-web-services amazon-s3 aws-sdk pre-signed-url

我正在使用aws-sdk获取S3的预签名网址。我有一个包裹在lambda中的函数。

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

module.exports = CreateRecord => {
  CreateRecord.controllers.createSignature = (event, context, callback) => {
    const s3 = new aws.S3({
      signatureVersion: 'v4',
    });

    const params = {
      Bucket: 'random-test-bucket002',
      Key: 'test-key',
      Expires: 100
    };

    s3.getSignedUrl('putObject', params, function(err, signedUrl) {
      let response;
      if (err) {
        response = {
          statusCode: 500,
          headers: {
            'Access-Control-Allow-Origin': '*',
          },
          body: JSON.stringify({
            error: 'Did not receive signed url'
          }),
        };
      } else {
        response = {
          statusCode: 200,
          headers: {
            'Access-Control-Allow-Origin': '*', // Required for CORS support to work
          },
          body: JSON.stringify({
            message: `Url successfully created`,
            signedUrl,
          })
        };
      }
      callback(null, response);
    });
  };
};

此代码完美无缺,我收回了预先签名的网址。当我在前端运行此代码时:

postImage(uuid) {
    const getSignature = 'https://xyz.execute-api.us-east-1.amazonaws.com/dev/v1/createSignature';
    axios.get(getSignature)
    .then(res => {
        const signatureUrl = res.data.signedUrl;
        // I have a blob that I store in file
        // uuid is passed from another function
        const file = new File([this.state.cover], uuid);

        axios.post(signatureUrl, file)
        .then(s3Res => {
            console.log(s3Res);
        });
    });
}

我一直遇到的错误是:我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。我尝试了一些内容类型的标题,但没有做任何事情。我可以将预先签名的网址传递给aws-sdk中的某个功能吗?我已经查看过很多帖子,但似乎无法解决问题。

1 个答案:

答案 0 :(得分:2)

使用预先签名的PutObject网址上传到S3时,您应该使用HTTP PUT方法而不是HTTP POST方法上传文件。您可以将对象POST到S3,但这些对象是为基于浏览器的上传而设计的。