AWS S3 预签名 URL 策略

3

目前正在进行一个项目,基本上是存储在 AWS S3 上的在线画廊。目前的流程是,前端网页向托管在 EC2 上的 API 服务发送请求,然后返回预签名 URL。该服务将使用 Go 语言和 aws-sdk-go-v2。

URL 是有时间限制的,设置为 PUT 对象类型。不幸的是,我还没有弄清楚如何限制将要上传的文件的其他方面。理想情况下,URL 应该受到限制,只接受图片等内容。

我的搜索结果各不相同,有些说可能可行,有些说不可能,有些则根本没有涉及我所做的事情。

关于设置 POST/PUT 策略的答案很多,但它们要么适用于 V1 SDK,要么就是完全不同的语言。 这个答案里甚至提供了一些可以实现此功能的库 ,但我不想立即使用它,因为它需要在代码中或环境中的某个地方放置访问密钥(尝试利用 EC2 的 IAM 角色自动化该过程的好处)。

有人知道这是否仍然是 SDK v2 上的问题吗?出于一致性的考虑,我想保持在 SDK v2 上。

编辑:几乎忘记了。我看到 S3 也可以在上传完成后跟随链接。这仍然可能吗?如果可以,那将是一个很好的验证,以便可以记录已上传的内容。

2个回答

4

在返回预签名的PUT URL之前,您可以尝试通过后端API验证文件名。一个不太安全但是可行的方法是在前端客户端验证文件内容。


前端验证是必须的。虽然以这种速度进行,我认为在传递到S3之前最好将文件中继到后端API。EC2带宽显然并不那么昂贵。但是,谢谢! - Krittercon

1
很遗憾,我还没有找到一种通过Content-Type限制上传的方法,但我发现了一些小技巧可能会对您有所帮助。

首先,虽然这有点像用大锤子砸蚂蚁,但您可以通过应用存储桶策略来按文件名进行限制。这个AWS Knowledge Center的示例只允许上传几种图像类型。

{
  "Version": "2012-10-17",
  "Id": "Policy1464968545158",
  "Statement": [
    {
      "Sid": "Stmt1464968483619",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111:user/exampleuser"
      },
      "Action": "s3:PutObject",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*.jpg",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*.png",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*.gif"
      ]
    },
    {
      "Sid": "Stmt1464968483619",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "NotResource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*.jpg",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*.png",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*.gif"
      ]
    }
  ]
}

第二种方法,您可以在文件上传后自动触发Lambda函数。使用此方法,您可以检查上传后想要的文件的任何内容。通常我更喜欢这种方法,但问题是如果文件无效,实际上没有任何即时反馈。
我的最后一个选项需要客户端做更多工作,这是我最近使用的方法。如果您正在上传非常大的文件,则S3要求您使用分段上传。这不是像HTML表单一样的多部分;而是将文件分成块并上传每个块。如果您的文件足够小(我认为限制为5GB),则只需进行单个部分。上传所有部分后,必须向服务器发出另一个调用,以完成与S3的上传。这是您可以添加一些文件验证并在客户端仍在上传页面时响应客户端的地方。

如果有人上传了一个5GB的图像,我会有点担心,哈哈。文件扩展名不完全是我所希望的,但它可以工作。Lambda函数很好,因为我确实需要一个验证系统来通知上传完成的情况。谢谢! - Krittercon
不客气。我会避免前端验证,而是将过滤器放在HTML输入上(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept)。服务器验证才是真正重要的。 - geowa4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接