【问题标题】:Pre-signed url for multiple files?多个文件的预签名网址?
【发布时间】:2016-07-20 13:03:17
【问题描述】:

我已经编写了一个实现,用于为 aws-s3 上的存储桶生成预签名 URL。它工作正常,用于获取单个文件/对象。

如何为整个目录生成预签名 URL?这么说吧,在我的 s3 存储桶上,有多个文件夹,里面有自己的小型 html5 应用程序。每个文件夹都有自己的一组 html、css、js 以及媒体文件。在这种情况下,我不会为单个对象生成预签名 URL。

如果我为单个文件提供预签名的 url,例如:文件夹的 index.html,则该文件还需要加载 css、js 和媒体文件。我们没有签名网址的文件。

我只是不太确定如何实施。

【问题讨论】:

  • 这是一个静态网站吗?
  • 是的。我知道预签名 URL 仅适用于单个对象。我现在使用静态托管作为解决方法,但有些目录需要授权。浏览 aws 文档,我可以创建 IAM 用户,因为我可以对它们进行分组,所以效果很好,但这听起来像是出于开发目的,不一定适用于最终用户。

标签: amazon-web-services amazon-s3 aws-sdk


【解决方案1】:

不,他们需要提供 API 以允许您先上传多个文件。这是 API 的限制,而不是预签名。

Is it possible to perform a batch upload to amazon s3?

【讨论】:

    【解决方案2】:

    这绝对是可能的,而且多年来一直如此。生成预签名 URL 时必须使用 conditions,特别是 starts-with。见官方Amazon Documentation

    例如,这里是 Python 与 Boto3 生成一个预签名的 POST url:

        response = s3.generate_presigned_post(
            "BUCKET_NAME",
            "uploads/${filename}",
            Fields=None,
            Conditions=[["starts-with", "$key", "uploads/"]],
            ExpiresIn=(10 * 60),
        )
    

    【讨论】:

    • 谨慎使用 key 开头,但这有效!
    • 我需要在该方法的关键参数上指定 ${filename} 吗?但我想添加多个具有相同预置帖子 url 的不同文件。我想使用"uploads/" 而不是"uploads/${filename}"
    • @DavidMerritt 你能详细说明为什么需要谨慎吗?
    【解决方案3】:

    没有。预签名 URL 仅对一个对象有效。

    【讨论】:

      【解决方案4】:

      首先要做的事情: AWS S3 是一个键值存储,每个对象aaa/bbb/ccc/ddd/index.html 只是一个名称。没有“文件夹”的概念(即使您可能会误以为它们存在于 UI 中)。

      为了为多个“文件”创建一个预签名的 url,您必须进行一些预处理。将所有必要的文件拉到本地,将它们压缩并将 zip 存档放在 S3 上,然后生成 zip 存档的预签名 URL。

      【讨论】:

      • 从技术上讲,S3 是一个没有文件夹的 KV 存储,但实际上那里确实存在“文件夹”。您已经可以设置存储桶策略based on key path 以在文件夹上设置策略。但是预签名 URL(当前)不支持部分密钥路径。即使他们这样做了,它也无助于 OP,因为 HTML 应用程序仍在链接到没有预签名 URL 的资源(css、js 具有相同的键前缀)。
      【解决方案5】:

      对于 2021 年关注此问题的其他人 - 我发现从 S3 存储桶下载整个文件“文件夹”的最简单方法是更改​​上传“文件夹”的方式。我没有递归上传,而是将对象压缩到单个 zip 存档中,然后上传 zip 存档。它不会直接回答问题,而是一种快速的解决方法。这是我用来解决这个问题的示例 python 代码:

      from shutil import make_archive

      from boto3 import client

      make_archive(name_of_zipped_folder, 'zip', path_to_outdir)

      然后将此压缩文件夹上传到 s3

      aws s3 cp name_of_zipped_folder s3://bucket_name/name_of_zipped_folder

      然后使用 boto3 代码为该压缩文件夹生成预签名的 url

      client('s3', 'us-east-1').generate_presigned_url('get_object', Params={'Bucket': bucket_name,'Key': name_of_zipped_folder}, ExpiresIn=120)

      【讨论】:

        【解决方案6】:

        这将为 S3 上的现有对象生成预签名 URL。在您的情况下,您可以列出所有对象(使用 keyName)并递归调用上述方法。

        public String generatePreSignedUrl(String bucketName, String keyName){
        
            Date expiration = new Date();
            long mSec = 60000l;     //Time in millis
            expiration.setTime(mSec);
        
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, keyName);
            generatePresignedUrlRequest.setMethod(HttpMethod.GET);
            generatePresignedUrlRequest.setExpiration(expiration);
        
            URL url = s3.generatePresignedUrl(generatePresignedUrlRequest);
            return url.toString();
        }
        

        PS:AWS SDK 提供 API 来列出存储桶下的对象,您可以选择所需的对象。

        【讨论】:

          猜你喜欢
          • 2023-03-25
          • 2022-11-23
          • 1970-01-01
          • 2022-10-09
          • 1970-01-01
          • 2020-11-16
          • 1970-01-01
          • 2016-11-25
          • 2020-08-25
          相关资源
          最近更新 更多