使用预签名的 url 将文件发送到 s3 存储桶会出现 403 错误 (SignatureDoesNotMatch)

Posted

技术标签:

【中文标题】使用预签名的 url 将文件发送到 s3 存储桶会出现 403 错误 (SignatureDoesNotMatch)【英文标题】:Sending file to s3 bucket using presigned url gives 403 error (SignatureDoesNotMatch) 【发布时间】:2021-05-22 01:06:40 【问题描述】:

我正在我的应用程序的服务器端生成一个预签名 URL,如下所示:

const s3 = new AWS.S3(
    region: 'us-west-2',
    signatureVersion: 'v4',
);
const params = 
    Bucket: 'bucketName',
    Key: fileName,
    ContentType: 'text/csv',
    Expires: 120
;
    
return s3.getSignedUrl('putObject', params);

然后我尝试使用如下所示的 ajax 调用将文件放入我的 S3 存储桶:

$.ajax(
    url: url
    type: 'PUT',
    data: file,
    processData: false,
    contentType: 'text/csv',
    success: function () 
        console.log('Uploaded data successfully.');
    ,
    error: function (xhr) 
        console.log(xhr);
    
);

但是,当我尝试执行此操作时,我收到 403 Forbidden 错误,并且 XML 显示 SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method.

我已确保ContentType 在生成预签名 URL 和将文件放入 S3 存储桶时相同。无论我做什么,都没有任何效果,我仍然得到这个 403 错误。我试图为ContentTypebinary/octet-stream,但没有奏效。我试图做ACL: 'public-read',但没有奏效。我的存储桶中也配置了 CORS,所以我知道这不是问题(我对此有不同的错误)。我确实注意到在网络调用中,它是这样说的:

Request URL: https://bucket-name.s3.us-west-2.amazonaws.com/fileName?Content-Type=text%2Fcsv&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAXBWQUNDKKHHYM5GH%2F20210219%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210219T015308Z&X-Amz-Expires=120&X-Amz-Security-Token=FwoGZXIvYXdzEIv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDOQ1EV3FIT00%2Fuo1BCKyAROysQ9G5PY9RFLeS8GwBLPEo7LCEJWstwki7nZatfddDczn0GKO7GwNEe5Qs%2BsLtMZv2xPTXo3Bwur%2BIhH7jV35HHQm976s1mOf8JZe2g%2BimUGNwLxBKY%2BrhWsN8yryNrd6k1VBRf1R9No9Jh%2FIumuwiVEoFLvVBHtILB9i53FdDo%2BJ8T%2BMCliV22SGBAwPQnYk8xvbo1%2B%2B%2B%2BAu%2FwVFl3tvG2yo7PHLzPpKqcpyJq4pMwko3aK8gQYyLUl0hZCTtit2cvBD5YAo57aMZBdTlpN5Wx3q27PSQZ1d8Bq1lQY%2BIQVkPlxZ%2Fw%3D%3D&X-Amz-Signature=446c16abde4d278c42c72373c85a6d44f959330468076e6bd888a8e2816b2b86&X-Amz-SignedHeaders=host
Request Method: PUT
Status Code: 403 Forbidden
Remote Address: 52.218.246.105:443
Referrer Policy: strict-origin-when-cross-origin

对于响应标头:

Referrer Policy: strict-origin-when-cross-origin
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Connection: close
Content-Type: application/xml
Date: Fri, 19 Feb 2021 01:53:09 GMT
Server: AmazonS3
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method

并且请求标头有Content-Type: text/csv...虽然不确定这是否重要

任何帮助将不胜感激。我从字面上搜索了整个谷歌,没有人说出于某种原因对我有用..

【问题讨论】:

文件名一样吗? @Marcin 是的,他们是一样的 【参考方案1】:

原来我的存储桶出了点问题,这就是我收到此错误的原因。我尝试写入的存储桶到底有什么不同仍然未知。我尝试了另一个 S3 存储桶,它工作正常

【讨论】:

【参考方案2】:

检查您的API key and secret,因为SignatureDoesNotMatch 错误通常是指 API 密钥和秘密不匹配,请参考之前的答案:

https://***.com/a/38837566/6687588

【讨论】:

嗯,我之前确实看过那个帖子,但我决定尝试做那个人对AWS.config.update(accessKeyId: 'id-omitted', secretAccessKey: 'key-omitted') 所做的事情。这次我实际上遇到了一个不同的错误:<Code>InvalidAccessKeyId</Code><Message>The AWS Access Key Id you provided does not exist in our records.</Message>.. 我对预签名 URL 进行的 ajax 调用似乎没有使用相同的访问密钥 ID?【参考方案3】:

添加答案,因为我无法发表评论

你能检查一下为什么你的“X-Amz-Signed-Headers”没有和“host”一起出现内容类型吗?

因为这是“参数”的一部分,因此也是签名计算的一部分,你应该看到

X-Amz-SignedHeaders=content-type%3Bhost 

而不是?Content-Type=text%2Fcsv

【讨论】:

以上是关于使用预签名的 url 将文件发送到 s3 存储桶会出现 403 错误 (SignatureDoesNotMatch)的主要内容,如果未能解决你的问题,请参考以下文章

使用 AlamoFire 和预签名 URL 将图像上传到 S3 存储桶时出现问题

如何使用预签名的 url 将对象放入 amazon s3?

使用预签名 URL 将文件上传到 Amazon S3 时出现 CORS 错误

使用预签名的 url PUT 到 S3 会出现 403 错误

使用其预签名 URL 从 AWS s3 读取文件的内容

Amazon S3 预签名 URL - 手动或一次性上传无效