首页 > 解决方案 > 如何在不公开文件的情况下将文件从一个 S3 存储桶访问到另一个存储桶?

问题描述

要使其他 S3 存储桶可以访问文件,我们需要将存储桶公开或启用 cors 配置。

我在一个作为静态网站托管的公共存储桶中有一个 HTML 页面。在另一个桶中,我有 mp3 文件。此存储桶不公开。从第一个存储桶中,HTML 调用一个 script.js 文件,该文件尝试使用资源 URL 访问第二个存储桶中的 MP3 文件。这不是直接可能的,并且会产生 403 错误。因此,我为 bucket-2 编写了一个 CORS 配置,其中包含 . 尽管如此,该脚本仍无法访问 MP3 文件。我还尝试使用静态网站 URL 而不是 ARN。再次收到 403 错误。是否可以在不公开 bucket-2 的情况下启用 script.js 访问 bucket-2 中的 mp3 文件?

标签: amazon-web-servicesamazon-s3permissionscorsbucket

解决方案


您必须了解您的 javascript 是在客户的浏览器窗口中运行的,因此这是试图访问您的第二个存储桶中的 mp3 文件的浏览器,而不是第一个存储桶。

知道这一点,除了打开对第二个存储桶的访问权限并尝试使用 CORS 之外,没有简单的解决方案可以解决您的问题(但单独的 CORS 不会提供对私有存储桶的访问权限)

提案1:手动生成签名

如果您只想授予对第二个存储桶中的几个文件(而不是所有文件)的访问权限,我建议在您的 javascript 中包含一个完全签名的 URL,该 URL 指向第二个存储桶中的对象。根据S3 文档,签名 URL 允许访问非公共存储桶中的单个对象。然而,生成签名并非易事,需要一些代码。

我编写了这个命令行实用程序来帮助您为私有存储桶中的给定对象生成签名。 https://github.com/sebsto/s3sign

AWS 命令​​行现在也有一个presign选项 https://docs.aws.amazon.com/cli/latest/reference/s3/presign.html

此外,签名是有时间限制的,最长期限为7 天。因此,如果您选择此方法,则需要每周重新生成链接。这不是非常可扩展的,但可以很容易地自动化。

提案 2:在 Web 服务器上生成动态签名

如果您决定放弃客户端 Javascript 并改用服务器端生成的页面(使用 Python、Ruby、PhP 等...和服务器),您可以从服务器动态生成签名。这种方法的缺点是您需要一台服务器。

提案 3:动态签名生成,无服务器

如果您熟悉 AWS Lambda 和 API Gateway,您可以创建一个无服务器服务,该服务将动态地将签名 URL 返回到您的 MP3 文件。您的静态 HTML 页面(或客户端 Javascript)将调用 API Gateway URL,API Gateway 将调用 Lambda,而 Lambda 根据路径或查询字符串返回 MP3 的适当签名 URL。

提案 2 和 3 有与之相关的 AWS 成本(运行 EC2 服务器,或 API 网关和 Lambda 执行时间),因此请务必在选择选项之前检查AWS 定价。(提示:提案 3 将更具成本效益)

真正的问题是你为什么要创建这个?为什么不能在需要时使用细粒度的 S3 访问策略将所有公共内容放在同一个存储桶中。


推荐阅读