AWS S3签名URL获取私有文件

3

问题:
用户将上传文件并稍后获取。存储桶和对象将是私有的。为了上传文件,我正在使用 S3 预签名 URL。前端将获取此 URL 并将文件上传到此 URL。现在问题与获取文件有关,在上传过程中,我正在创建一个预签名 URL 并将其存储在数据库中,以便稍后获取。

    
    const params = {
        Bucket: process.env.DEFAULT_TENANT_BUCKET,
        Key: filePath,
        Expires: expiryTime
    };

    const s3 = new AWS.S3();
    let uploadURL =  s3.getSignedUrl('putObject', params);
    return uploadURL;

    const s3 = new AWS.S3();
    let uploadURL =  s3.getSignedUrl('getObject', params);
    return getURL; // This will be stored in database

但是,即使我们没有明确指定任何过期时间,签名的URL也会在一段时间后过期。因此,我不能将这个预签名的URL存储在数据库中。

另一种方法:
不要将 getUrl 存储到数据库中,而是将 filePath 存储到数据库中,并在前端获取数据时创建并获取已签名的 URL。
上述方法的问题:

  1. 如果用户以 Excel 格式下载用户列表并包含文件的 URL,则该 URL 也会在一段时间后失效。
  2. 当用户列表很大时,创建已签名的 URL 可能需要一定的时间。

有更好的解决方法吗?


没有更好的方法。如果您不希望文件URL过期,您必须使用常规的S3路径,并要求用户通过Cognito对您的系统进行身份验证。如果您不想进行任何形式的身份验证,则必须将对象设为公共。 - Marcin
真是令人失望。 - Shadab Faiz
2个回答

1
一种解决此问题的方法是构建能随需求向经过身份验证的客户端提供预签名URL的服务器端代码。
您需要为数据库中的每个对象存储一个固定的给定URL。例如,这很容易创建:https://api.myserver.com/short-uuid。这是最初提供给客户端的URL。当客户端想要获取私有文件时,它会调用该URL的HTTP GET请求。
您需要实现服务器端代码来响应这些GET请求。您可以使用简单的API Gateway和Lambda项目来完成此操作。客户端具有固定的URL,GET该URL并带有相关的认证令牌,您的服务器端应用程序对客户端进行身份验证,在提供的URL中查找“short-uuid”参数,并检索关联的S3对象的桶和密钥,预签名URL,并在HTTP 302重定向中将其返回到客户端。客户端重定向到所请求的预签名S3 URL并下载文件。

我们目前的实现与此类似。我们将对象路径存储在数据库中。当前端获取这些数据时,我们为文件创建预签名 URL 并将其发送回前端。但正如我在问题中所说,如果用户需要下载可能包含这些文件 URL 的 Excel 文件,则此实现将失败。(预签名 URL 无法永久存在。) - Shadab Faiz
XLS中的URL也将采用https://api.myserver.com/short-uuid的形式。当客户端单击它以检索相关文件时,同样需要进行身份验证,并将重定向到预签名URL。显然,身份验证部分是您需要解决的挑战,除非您想共享公共URL,我认为您不会这样做。顺便说一下,您提到了创建预签名URL的速度问题 - 实际上这是一个快速的过程(每秒1000个)。 - jarmod

0

在使用预签名URL时,最好的方法是在请求时对URL进行签名。这样可以避免超时问题。问题变成了为什么要使用预签名URL?它们非常适合上传,并且在下载方面也有用处,但似乎您并不想将链接设为私有,只是不想暴露存储桶。在这种情况下,最好的选择是使用CloudFront。您的CloudFront分发可以指向仍然是私有的S3存储桶。您可以使用预签名URL进行上传,但文件的链接通过CloudFront进行传输,因此它们不需要签名。


我对CloudFront的知识不够丰富。你有类似的博客或示例可以分享吗? - Shadab Faiz
如果你在谷歌上搜索这个主题,会有很多博客。https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html是AWS提供的一个非常基础的教程。 - Jason Wadsworth

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