如何使用预签名 URL 调试 S3 上传?

Vin*_*ent 4 amazon-s3 amazon-web-services aws-sdk

不久前,我实现了一个 PDF 上传功能,其中我的前端调用我的后端,它调用getSignedUrl()Amazon 的 JavaScript SDK 来获取前端应该能够使用PUT请求上传文件的 URL 。

这已经工作了一段时间了,今天,我尝试实现类似的功能来上传图像(到不同的 S3 存储桶)。不幸的是,虽然它看起来设置相同,但PUT上传结果

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId><!-- A request ID --></RequestId>
    <HostId><!-- A host ID --></HostId>
</Error>
Run Code Online (Sandbox Code Playgroud)

这并不是很有帮助,所以现在我正在尝试找出最好的调试方法。

我检查过的:

  • 桶存在
  • 存储桶的 CORS 配置与上传工作的存储桶的 CORS 配置相同
  • 桶策略和工作桶一样,只是它所s3::GetObject在的资源是指这个新的桶
  • 访问控制列表是一样的
  • 它位于正确的区域
  • 预签名 URL 看起来与工作 URL 相同
  • 我的浏览器为失败和工作PUT请求发送相同的 HTTP 标头
  • OPTIONS首先发送的请求也是如此

我还能检查什么?

Vin*_*ent 5

所以有一件事我没有正确检查:

预签名 URL 允许您访问 URL 中标识的对象,前提是预签名 URL 的创建者有权访问该对象。也就是说,如果您收到用于上传对象的预签名 URL,则只有在预签名 URL 的创建者具有上传该对象所需的权限时,您才能上传该对象。

我从 AWS Lambda 函数生成了 URL,我必须为其添加 IAM 策略,如下所示:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::<bucket name>/*"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是一个很好的答案,但从它解决您遇到的具体问题的意义上来说,我仍然坚持寻找一个更广泛地回答“如何调试失败的签名 S3 链接”的答案。尤其是如果我不是遇到麻烦的一方的话。 (3认同)