【问题标题】:AWS S3: SignatureDoesNotMatch when trying to get a signed URL to do browser uploadAWS S3:尝试获取签名 URL 以进行浏览器上传时的 SignatureDoesNotMatch
【发布时间】:2017-09-21 02:40:52
【问题描述】:

我正在尝试将文件从我的浏览器上传到 S3(Base64 格式),但似乎我必须首先获得一个签名的 URL,但我在尝试获取这个签名的 URL 时从未得到正确的响应。这是我所做的:

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

MyController.get('/s3_sign', (req, res) => {

  let s3 = new aws.S3();
  aws.config.update({
    accessKeyId: "AKIAIWUTWWWBZM3IZNJAQ",
    secretAccessKey: "My_Secret_Key_Without_Any_Special_Characther"
  });

  let params = {
    Bucket: 'my-bucket-name',
    Key: 'file.jpg',
    Expires: 300
  };

  const url = s3.getSignedUrl('putObject', params, function(err, data){
    if (err) {
      console.log("Error uploading data: ", err);
      res.json({success: false})
    } else {
      console.log("URL: ", data);
      res.json({success: true, data: data})
    }
  });

})

我在本地测试,当我点击这个 URL 时,我得到了这个响应:

<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>AKIAIWUTWWWBZM3IZNJAQ</AWSAccessKeyId>
<StringToSign>
GET 1505923677 /my-bucket-name/button.png
</StringToSign>
<SignatureProvided>J41L/yY6SipfRcQa6yEjlrWahY8=</SignatureProvided>
<StringToSignBytes>
47 45 54 0a 0a 0a 31 35 30 35 39 32 33 36 37 37 0a 2f 63 6f 6e 70 61 73 73 2d 64 65 76 2f 63 6f 6e 70 61 73 73 2d 63 74 61 2d 62 6c 75 65 2d 31 78 2e 70 6e 67
</StringToSignBytes>
<RequestId>62398629E214AC9D</RequestId>
<HostId>
ZD9X7KkvhtKA5PBjfQXGo+IhHRSa0vVnWyEhdepB2O8h50OEP5iEsCHpV/UY27QqPFEgHf0kLu0=
</HostId>
</Error>

我已经检查过了,我的凭据是正确的,没有任何空格,任何特殊字符。但我不知道为什么我从来没有让它工作。

我不确定它是否相关,因为我什至无法获得签名 URL(在上传之前),但我的 CORS 设置如下:

<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Content-Type</AllowedHeader>
    <AllowedHeader>x-amz-acl</AllowedHeader>
    <AllowedHeader>origin</AllowedHeader>
</CORSRule>
</CORSConfiguration>

我期待一些关于如何克服这个问题的想法。

【问题讨论】:

  • 您是否正在调用带有数据的 PUT 到预签名的 URL?想知道为什么当您的 PUT 用于 /my-bucket-name/file.jpg 时诊断显示 GET /my-bucket-name/button.png。 PS 你永远不应该在网页的源代码中包含访问密钥和密钥。
  • 该错误表明您的访问密钥和密码错误。您一直在提到“没有特殊字符的秘密”。你的秘密应该和它给你的完全一样。不要删除任何特殊字符。作为测试,您应该能够使用您的访问密钥执行s3:ListBuckets 以验证它是否正常工作。
  • 实例化 S3 客户端时,是否指定了与存储桶所在位置对应的区域?某些区域要求使用特定的签名算法,需要指定区域
  • @MattHouser 很抱歉混淆了,我的意思是密钥和秘密都可以,我没有改变任何东西。我什至可以使用 aws-sdk 列出我的对象。问题可能是别的。

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


【解决方案1】:

您正在尝试对 PUT url 执行 GET 操作。如果你想为 GET 方法获取一个签名的 url,

var params = {Bucket: 'bucket', Key: 'key', Expires: 60};
var url = s3.getSignedUrl('getObject', params);
console.log('The URL is', url); // expires in 60 seconds

详细文档在,

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property

【讨论】:

  • 我正在尝试从浏览器执行上传,上面的代码在 API 中,只是为了获取这个签名的 URL 而创建的,我可以看到它是正确的,因为我想上传它我有打电话给putObject 而不是getObject。正确的?但我不知道为什么我在回复中收到 GET。
猜你喜欢
  • 1970-01-01
  • 2016-10-21
  • 2015-09-05
  • 2016-11-25
  • 2019-09-13
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多