错误:我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法

lea*_*ner 3 amazon-s3 node.js

从过去 3 天开始,我陷入了同样的签名问题。我不明白如何摆脱这种情况。

我正在尝试通过以下方式获取预先签名的网址:

    s3.getSignedUrl('putObject',
    event.pre_signed_url =    
           {Bucket:config.awsBucket,Key:event.filename}
      ); in Node js.
Run Code Online (Sandbox Code Playgroud)

我使用这个预先签名的 url 上传 s3 存储桶中的图像文件:

   request({
      method:'PUT',
      url: event.pre_signed_url,
      ContentType: 'image/png',
      body: fs.createReadStream('./image.png')}
      , function(err, res, body)
   { if(err)console.log(err); return callback(body); }
  );
Run Code Online (Sandbox Code Playgroud)

并且文件已成功上传到 s3 存储桶,我可以在 aws s3 存储桶控制台中看到。

问题是,如果我尝试从终端使用 curl 放置任何其他图像文件或尝试在浏览器中打开该 url,我得到的预签名 url 会给我签名不匹配错误。

如果我做错了或者我对预签名 url 用法的理解是错误的,请指导我。

far*_*llw 6

我在使用S3.getSignedUrl('putObject'服务器端时遇到了同样的问题,然后尝试使用该 url 客户端。您正在为未在参数中设置的请求设置额外的标头。

在我的案例中,我注意到可能与您的案例相关的是使用所有S3.getSignedUrl考虑请求标头创建的签名。因此,如果您正在生成一个 URL,它将失败并显示您收到的相同错误消息,除非使用相同的标头发送。

失败的一个例子:像这样生成..

var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000 };
s3.getSignedUrl('putObject', params, function (err, url) {
      if(err){
        return cb(err);
      }
      return cb(null, url)
    });
Run Code Online (Sandbox Code Playgroud)

使用生成的相同 url 时,以下请求失败。此请求是从浏览器发出的。

RequestMethod: Put
Headers: {
    Accept:*/*
    Accept-Encoding:gzip, deflate, br
    Accept-Language:en-US,en;q=0.9
    Connection:keep-alive
    Content-Length:11768
    Content-Type:application/x-www-form-urlencoded; charset=UTF-8
}
Run Code Online (Sandbox Code Playgroud)

不同之处在于上面创建的签名不包括内容类型,其中请求确实指定了内容类型。params 需要匹配 headers,否则抛出的错误将是签名不匹配。

成功例子如下:

var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000, Content-Type: 'application/x-www-form-urlencoded; charset=UTF-8' };
s3.getSignedUrl('putObject', params, function (err, url) {
      if(err){
        return cb(err);
      }
      return cb(null, url)
    });
Run Code Online (Sandbox Code Playgroud)

  • 现在是“ContentType”,而不是“Content-Type” (4认同)