【问题标题】:S3 pre signed url without path没有路径的 S3 预签名 url
【发布时间】:2019-08-31 06:27:36
【问题描述】:

我需要有一种方法让客户端将数据上传到 S3,而无需向他们显示文件的完整位置(路径)。这对 AWS S3 预签名 URL 可行吗?

我正在使用 boto3

s3.client.generate_presigned_url(
  ClientMethod='put_object', 
  ExpiresIn=7200,
  Params={'Bucket': BUCKET, 'Key': name}
)

但结果会是:

https://s3.amazonaws.com/MY_BUCKET/upload/xxxx-xxxx/file-name.bin?AWSAccessKeyId=XXXX&Signature=XXXX&Expires=XXXX

我需要这样的东西,不会在路径中显示密钥名称 (/upload/xxxx-xxxx/file-name.bin)。

如果不是预签名的 url,我还有什么其他解决方案?

【问题讨论】:

  • 我只是提出一个想法:您可以有一个简单的 Lambda 函数,在上传时触发,然后移动/重命名上传的对象。
  • @AlexanderAzarov 这正是我想要避免的,但我想我可以做到
  • Lambda@edge 在这里可能有用。
  • 您是否有任何特殊原因不希望他们看到路径/键?知道它不会给他们任何额外的访问权限。
  • @JohnRotenstein 我知道,但是由于一些遗留代码,该路径在另一个应用程序上是打开的。在我们可以完全迁移客户之前,有必要隐藏它。

标签: amazon-web-services amazon-s3 boto3 boto


【解决方案1】:

我认为最好的方法是使用 AWS Cloudfront 分发文件。您可以将 Cloudfront 分发的来源设置为 MY_BUCKET.s3.amazonaws.com。也可以使用MY_BUCKET.s3.amazonaws.com/upload 等子文件夹作为来源。

Cloudfront 将使用生成的 CDN 端点域在 S3 源中为您的文件提供服务,或者也可以设置和使用自定义域。

https://d111111abcdef8.cloudfront.net/upload/xxxx-xxxx/file-name.bin https://uploads.example.com/upload/xxxx-xxxx/file-name.bin

如果您使用子文件夹作为来源:

https://uploads.example.com/xxxx-xxxx/file-name.bin


有关在 Cloudfront 上将 S3 存储桶设置为源的更多信息:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistS3AndCustomOrigins.html#concept_S3Origin

更多关于使用 S3 Bucket 的目录路径作为源的信息:https://aws.amazon.com/about-aws/whats-new/2014/12/16/amazon-cloudfront-now-allows-directory-path-as-origin-name/

有关自定义 URL 的更多信息:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html

【讨论】:

  • 当然,我使用 cloudfront 与 S3 交互,这对我的上传问题毫无帮助。
【解决方案2】:

这不是一个完整的答案,但是太长了,无法发表评论。

我认为您应该能够使用 API Gateway 作为 S3 的代理来隐藏路径。您仍然可以使用预签名的 url,但您可能需要创建预签名的 API Gateway url,而不是预签名的 S3 url。我自己从来没有做过——我也不能在不久的将来尝试它——但我会尽力说明我认为它是如何完成的,也许其他人可以尝试并写一个更完整的回答。

首先,我们需要设置一个 API 网关端点,作为 S3 的代理。

AWS 在how to make a general proxy for S3 上有非常详尽的文章,我认为您可以通过修改代理的 PathOverride 使您的自定义端点指向 S3 中的特定存储桶和文件夹。如果您查看 AWS 文档的 this section 中的 PathOverrides 的屏幕截图,您可以看到他们已将路径覆盖设置为 {bucket}/{object},但我认为您可以将 PathOverride 设置为 mySecretBucket/my/secret/folder/{object},然后更新路径适当的映射。

接下来,您需要能够通过此代理使用预签名的 url。您可能有两种方法可以做到这一点。

可能起作用的第一件事是使 url 签名通过 API 网关传递到 S3。我知道可以以类似于路径参数的方式映射查询参数。您可能需要对预签名 URL 的签名参数执行一些 url 编码以使其工作——我不完全确定。

另一个选项是允许 Api Gateway 始终写入 S3,并且需要一个签名请求来调用您的代理端点。 This SO question 有一个非常详细的答案,在我看来它应该可以工作。

再一次,我知道这不是一个完整的答案,我也没有尝试验证它是否有效,但希望有人可以从这个开始,并为你的问题找到一个完整的答案。

【讨论】:

  • 我不满意,但至少你提供了 lambda 以外的东西,这似乎是合理的。我给你赏金,但现在让问题悬而未决
  • 这很公平。这不是一个非常令人满意的解决方案。似乎 AWS 添加混淆的预签名链接应该是一个非常简单的功能;我不知道他们为什么不支持它。
猜你喜欢
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多