我有一个一对一的聊天应用程序,用户可以彼此共享图像/视频文件。我的身份验证使用 Cognito,媒体文件存储在 S3 中,API 使用 Lambda 和 API Gateway。
对于包含图像的消息,我将图像的 ID 存储在 DynamoDB 上(例如 imageId:1234-5678-1234.jpg)。
我上传图像的方式是:lambda 生成一个 S3 预签名 URL -> 客户端通过该 URL 上传图像 -> 对每次上传执行以下步骤
对于媒体下载,我该如何进行?我想使用 CloudFront。我的想法是这样的,但我需要确认我是否追求正确的事情:lambda 生成一个 CloudFront 预签名 URL,该 URL 每 n 分钟过期 -> 客户端可以使用该预签名 URL 获取他们的任何照片。
但是,如果我想使用单个预签名 URL 一次获取多个文件(图像/视频)怎么办?
使用单个预签名 URL 获取多个文件并不直接可行,因为每个预签名 URL 对应于 S3 或 CloudFront 中的特定资源(对象)或路径。这意味着如果客户端需要下载多个文件,通常需要为每个文件生成单独的 URL。虽然有效,但这种方法对于批量下载来说可能会变得低效且麻烦。
一种安全的解决方案是使用 Lambda 函数动态处理批量下载。当客户端通过提供 imageId 请求多个文件时,Lambda 函数可以从 S3 检索文件,将它们压缩到 ZIP 存档中,将 ZIP 上传到临时 S3 存储桶,并为其生成预签名 URL。然后,客户端可以使用此单一预签名 URL 以 ZIP 形式下载所有请求的文件。临时存储和生命周期策略可确保 ZIP 文件在短时间内自动删除,从而优化成本。
或者,如果您的文件遵循通用路径结构(例如 /user/{userId}/files/),您可以将 CloudFront 配置为允许基于路径的预签名 URL。此方法使用户可以通过一个 URL 访问该路径下的所有文件。然而,这种方法缺乏粒度,因为它会公开路径中的所有文件,即使客户端只请求特定的文件。因此,虽然更简单,但此方法牺牲了对文件级访问的一些控制。
如果您想控制安全性,那么扩展 lambda 函数以允许压缩多个文件会更好。