放入 S3 预签名 URL 时如何修复“403 Forbidden”

Posted

技术标签:

【中文标题】放入 S3 预签名 URL 时如何修复“403 Forbidden”【英文标题】:How to fix '403 Forbidden' when putting to S3 presigned URL 【发布时间】:2019-10-02 19:22:37 【问题描述】:

我正在尝试使用预签名的 url 将图像放入 S3 存储桶。 我正在使用 SAM 在本地托管站点,并且 PUT 请求正常工作。但是,在我的产品服务器上运行命令时,我收到“403 Forbidden”错误。

值得注意的是 OPTIONS 请求工作正常,获取 200 代码,但接下来在发送 PUT 时获取 403 代码。

我已经尝试过的事情:

尝试将内容类型设置为我的图像类型 尝试将标题内容类型放入 尝试将 COMS 设置为允许 GET、POST、PUT、DELETE 尝试将我的 lambda 角色的访问权限设置为具有管理员访问权限

没有任何效果仍然得到'403 Forbidden'

JQuery Ajax:

$.ajax(
    url: presignedUrl,
    type: 'PUT',
    data: image,
    contentType: image.type,
    processData: false,
    success: function (response) 
        // window.location = '/Prod/';
    
);

创建预签名网址:

$cmd = $this->client->getCommand('PutObject', [
    'Bucket' => env('AWS_BUCKET'),
    'Key' => 'images/' . $request->input('image_name'),
]);

return $this->client->createPresignedRequest($cmd, '+20 minutes')->getUri();

来自“403 Forbidden”的一般:

Request Method: PUT
Status Code: 403 Forbidden
Referrer Policy: no-referrer-when-downgrade

来自“403 Forbidden”的响应标头:

Access-Control-Allow-Methods: GET, POST, PUT, HEAD
Access-Control-Allow-Origin: *
Connection: close
Content-Type: application/xml
Date: Wed, 15 May 2019 15:02:35 GMT
Server: AmazonS3
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-id-2: e5WZfJAQk24kl7kBoF+HU8+AOiR7ivTIcUZ71dZl0Ssged03RThlCRtku+AmhRRUwFe1p63cL4Q=
x-amz-request-id: 4767484BEBE4EC07

来自“403 Forbidden”的请求标头:

Accept: */*
Content-Type: image/jpeg
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/74.0.3729.131 Safari/537.36

本地 put 请求正常工作并且没有错误。

【问题讨论】:

【参考方案1】:

最终解决了这个问题。

我在 S3 客户端中指定了凭据,删除它们允许 lambda 函数的角色正确访问 S3。

不正确:

        $this->client = new S3Client([
            'credentials' => [
                'key'    => env('AWS_ACCESS_KEY_ID'),
                'secret' => env('AWS_SECRET_ACCESS_KEY'),
            ],
            'region' => env('AWS_DEFAULT_REGION'),
            'version' => 'latest',
        ]);

正确:

        $this->client = new S3Client([
            'region' => env('AWS_DEFAULT_REGION'),
            'version' => 'latest',
        ]);

【讨论】:

s3 适用于“GLOBAL”区域,因此 region 属性无用

以上是关于放入 S3 预签名 URL 时如何修复“403 Forbidden”的主要内容,如果未能解决你的问题,请参考以下文章

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

使用预签名 URL 上传到 Amazon S3 时限制对象大小

S3 预签名上传 url 错误

AWS S3 存储桶预签名 URL

如何使用 amazon sdk 为虚域生成预签名的 Amazon S3 url?

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