为啥从浏览器上传到 S3 时出现 403 错误?

Posted

技术标签:

【中文标题】为啥从浏览器上传到 S3 时出现 403 错误?【英文标题】:Why am I getting a 403 error when uploading to S3 from the browser?为什么从浏览器上传到 S3 时出现 403 错误? 【发布时间】:2015-11-23 12:27:01 【问题描述】:

因此,我尝试在此处查看以前的答案,但似乎没有任何效果。我正在使用 Dropzone,它似乎发出了一个 OPTIONS 请求以获取所有允许的 CORS 相关信息,但它似乎没有正确返回

所以通过查看 Chrome 开发工具,我有以下请求标头

Host: mybucket.s3.amazonaws.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:9010
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Access-Control-Request-Headers: accept, cache-control, content-type, x-requested-with
Accept: */*
Referer: http://localhost:9010/upload
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

这些是我得到的响应标头

HTTP/1.1 403 Forbidden
x-amz-request-id: 9BE37C4F32052EAB
x-amz-id-2: Zxg+v9AQ7G7sgMKz4P7xleUhrymyWGbBNNof8jFFsZ5n0Xw8T/mPovbMO55HZ5fL
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Fri, 28 Aug 2015 18:35:26 GMT
Server: AmazonS3

根据AWS documentation,我应该得到 Access-Control-Allow-MethodsAccess-Control-Allow-Headers,但我没有好像是。

我知道我的bucket有效,url有效,我bucket中的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>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

所以就发送的表单数据而言,我有以下几点:

acl
key
policy
x-amx-credential
x-amz-algorithm
x-amz-date
x-amz-signature

除了文件数据。我不认为我缺少任何东西

【问题讨论】:

显然有问题,不是返回的标头。亚马逊正在返回 403,这意味着它正在积极禁止您访问该地址,因此您无权访问。问题是,您发送的数据在哪里,是否包含您的 AWS 访问密钥、您要上传的文件、策略、签名和内容类型等? 所以我认为我拥有一切,但根据this 的说法,某些字段(如 x-amz-credential)奇怪地大写(所以它会是 x-Amz-Credential)。我也试过了,还是不行 【参考方案1】:

啊,真是太愚蠢了。根据enabling CORS 上的页面看来,对于 OPTIONS 请求:

预检请求的 Access-Control-Request-Headers 标头中列出的每个标头都必须与 AllowedHeader 元素匹配。

这意味着我必须在我的 CORS 策略中添加一堆以前缺失的行

<AllowedHeader>accept</AllowedHeader>
<AllowedHeader>cache-control</AllowedHeader>
...

【讨论】:

我通过 Rails 应用程序一次在 S3 上上传 8 个文件。但是在上传所有文件后,我没有在 dropzone 成功块中得到回调。但是,如果我上传 4 个文件,那么它就可以工作。我花了 2 天,但仍然没有得到任何解决方案。请帮忙【参考方案2】:

根据docs on enabling cors,您应该可以简单地使用*,因此您不必全部列出:

<AllowedHeader>*</AllowedHeader>

【讨论】:

【参考方案3】:

如果有人遇到这个问题,可能会出现 403,因为设置了错误的 contentType。

服务器端:

GeneratePresignedUrlRequest rq = new GeneratePresignedUrlRequest(bucketName, objectKey);
rq.setContentType("video/*");
...

客户端:

$.ajax(
                url:upUrl,
                type: "PUT",
                data: file,
                contentType:'video/*',
                cache: false,
                processData:false,
                success: function (data) 

                
              );

【讨论】:

以上是关于为啥从浏览器上传到 S3 时出现 403 错误?的主要内容,如果未能解决你的问题,请参考以下文章

仅从浏览器使用预签名 URL 上传时出现 AWS S3 CORS 错误

尝试将 AWS S3 数据库备份到 heroku postgres 时出现 403 错误

从 Nuxt 上传到 AWS S3 存储桶时出现 500 内部服务器错误

使用 Spark 访问 s3a 时出现 403 错误

尝试将文件(图像)上传到服务器时出现错误 403

运行 Amazon S3 示例时出现 Amazon AWS 403 InvalidAccesskey 错误