如何使用 Amazon S3 创建一次性下载链接?

Posted

技术标签:

【中文标题】如何使用 Amazon S3 创建一次性下载链接?【英文标题】:How can I create a one time download link with Amazon S3? 【发布时间】:2013-10-28 08:20:54 【问题描述】:

我想创建一个指向亚马逊 s3 托管文件的一次性下载链接。下载文件后,此链接即失效。

我希望该文件仍被托管,但访问者只能下载该文件一次。

我需要这个的场景是:我有一个文件下载网站,用户为文件付费。我希望用户只能从网站(和 Amazon s3)下载文件一次,我也不希望用户能够与其他人共享直接下载链接。

如果这不可能,我想知道如果可能的话,通过 IP 地址或 Cookie 来限制它是否更有效?

【问题讨论】:

我建议您将文件托管在自托管网站上并使用 php 等服务器端脚本语言处理下载 【参考方案1】:

没有办法告诉 S3 允许一个链接只使用一次。但是您可以创建一个只能在指定时间之前使用的链接。我所做的是将请求者重定向到在几分钟后过期的 S3 链接,因此他或她没有时间分享它。您可以使过期时间非常短,甚至几秒钟,只要他们的浏览器有时间接收重定向响应并遵循它。

【讨论】:

这听起来很适合我的情况,有什么关于如何解决这个问题的信息吗? 我看到你正在使用 PHP。我没有在这方面编程,但亚马逊有一个 SDK,看起来你应该使用 createPresignedUrl 方法。它记录在docs.aws.amazon.com/aws-sdk-php-2/latest/… 对于您的情况,比更通用的 createPresignedUrl 方法更好的是 getObjectUrl 方法:docs.aws.amazon.com/aws-sdk-php/latest/…。 $s3->getObjectUrl('bucket-name', 'object-key', '+5 分钟'); 我几乎肯定它适用于下载开始,因为那是身份验证发生的时候。但如果答案对你很重要,你可以很容易地创建一个测试。 @CharlesEngelke,你是对的,CloudFront checks the expiration date and time in a signed URL at the time of the HTTP request. If a client begins to download a large object immediately before the expiration time, the download should complete even if the expiration time passes during the download. If the TCP connection drops and the client tries to restart the download after the expiration time passes, the download will fail. From docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/… 同样应该适用于 S3【参考方案2】:

您可以编写“一次性 url 生成器”服务(以网站或 REST API 的形式)并利用 aws 联合用户功能来实现此目的。

考虑以下过程:

当用户想要一个一次性 URL 时,他们会将请求发送到您的“一个 时间网址生成器”服务。 您的服务会生成一个“一次性 URL”并将其返回给用户。 url 是与用户想要的 S3 资源的一对一映射。 当用户向“一次性 url”发出请求时,服务会使用 AWS 联合用户功能创建一个临时用户,并代表该临时用户生成一个 S3 预签名 url。 服务将响应发送回用户,重定向到预签名的 url。 用户跟随重定向,开始下载文件。 然后服务会删除临时用户。 (或者让它过期。)

【讨论】:

任何开源项目都有这个功能? @AviParshan 有没有类似的Java库? @sinu 我不知道

以上是关于如何使用 Amazon S3 创建一次性下载链接?的主要内容,如果未能解决你的问题,请参考以下文章

使用 php 从 Amazon s3 压缩和下载文件

如何使用来自外部链接的 SheetJS (Amazon S3) 解析 Excel 文件

使用 AWS 开发工具包从 Amazon S3 下载文件后如何删除文件

使用脚本在 Amazon S3 存储桶内创建子目录

如何在不下载文件的情况下搜索amazon S3存储桶中的文件内容

Amazon S3 boto - 如何创建文件夹?