CORS 上传文件到 S3,得到 SignatureDoesNotMatch 错误

Posted

技术标签:

【中文标题】CORS 上传文件到 S3,得到 SignatureDoesNotMatch 错误【英文标题】:CORS upload file to S3, got SignatureDoesNotMatch error 【发布时间】:2018-09-19 13:32:18 【问题描述】:

我想将视频文件从浏览器上传到 S3。 这是我的步骤:

    向 API Gateway 发送 GET 请求,调用 Lambda 以获取签名 URL。 使用PUT直接使用签名 URL 将文件上传到 S3。

第1步工作正常,我可以使用签名的URL通过curl上传文件:

curl -X PUT https://bucket-name.s3.amazonaws.com/testupload/videofile.mp4?AWSAccessKeyId=MY_AWS_ACCESS_KEY_ID&Expires=1523329853&Signature=XXXXX -T videophile.mp4

但是从浏览器上传文件到 S3,我得到了 403 响应,SignatureDoesNotMatch 错误:

SignatureDoesNotMatch

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

MY_AWS_ACCESS_KEY_ID

...

...

错误>

我检查了访问密钥是我在 lambda 中用来创建签名 url 的那个


客户端javascript

$.ajax(
    url : signedurl,
    type : "PUT",
    data : uploadfile,
    dataType : "text",
    cache : false,
    contentType : file.type,
    processData : false
)
.done(function() 

)
.fail(function(e) 
    console.error(e.status, e.statusText)
    console.error(e.responseText)
);

桶 CORS 配置:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">    
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

【问题讨论】:

【参考方案1】:

我找到了解决方案。在创建签名 URL 和 http 请求标头时需要Content Type(即使您可以通过curl 上传文件):

Lambda 代码(节点):

s3.getSignedUrl('putObject', 
    Bucket: "bucket-name",
    Key: `key/filename.ext`,
    ContentType: event.contentType,  // e.g.: "video/mp4"
    Expires: 300
)

客户端 JavaScript

$.ajax(
    url : signedurl,
    type : "PUT",
    data : uploadfile,
    cache : false,
    headers:
        'Content-Type': file.type  // e.g.: "video/mp4"
    ,
    processData : false
)

有用的链接:

Upload a file with $.ajax to AWS S3 with a pre-signed url Browser Uploads to S3 using html POST Forms

【讨论】:

这给了我一个错误:在 params 中找到了 Unexpected key ‘ContentType’。我认为 getSignedUrl 方法发生了一些变化。

以上是关于CORS 上传文件到 S3,得到 SignatureDoesNotMatch 错误的主要内容,如果未能解决你的问题,请参考以下文章

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

带有预签名 URL 和 CORS 问题的 S3 上传

将大于 1MB 的文件上传到 s3,出现 cors 错误。请求的资源上不存在“Access-Control-Allow-Origin”标头

Laravel + Plupload 上传到 S3 响应以进行预检无效 - CORS

通过 OPTIONS 后 S3 CORS 上传中止

使用 S3 的 React App 中的 CORS ORIGIN 错误