【问题标题】:How to efficiently allow for users to view Amazon S3 content?如何高效地让用户查看 Amazon S3 内容?
【发布时间】:2022-01-02 02:32:17
【问题描述】:

我目前正在使用 React-Native(前端)和 Flask/MongoDB(后端)创建一个基本应用程序。我计划使用 AWS S3 作为将要上传和查看的所有图像和视频的廉价云存储。我目前的想法(这可能完全关闭)是当用户上传内容时,它将通过我的 Flask API,然后到 S3 存储。当用户想要查看内容时,我不确定这里的攻击计划是什么。我应该使用我的 Flask API 作为代理,还是有办法直接在 S3 上发送指向内容的链接(这样可以避免通过我的 API 产生额外流量)?

我对使用 AWS 很陌生,如果已经有帖子讨论这个话题,请告诉我,我很乐意删除这个副本。我似乎找不到任何东西。

【问题讨论】:

    标签: amazon-web-services flask amazon-s3


    【解决方案1】:

    我应该使用我的 Flask API 作为代理,还是有办法直接在 S3 上发送指向内容的链接(这样可以避免通过我的 API 产生的额外流量)?

    如果内容是公开的,您只需提供一个直接指向 S3 存储桶上文件的 URL。

    如果内容是私有的,您可以在后端为您要授予访问权限的文件生成presigned url。此 URL 应在短时间内有效(例如:15/30 分钟)。如果它不可用,您可以重新生成它。

    此外,您可以生成一个预签名 URL,该 URL 可用于直接从前端上传到 S3 存储桶。如果您不希望上传流量通过后端或想要更快的上传速度,这可能是一个选项。

    【讨论】:

      【解决方案2】:

      有一个API boto3,试试用吧。

      没那么难,我做过类似的,这里贴代码。

      我已经像@Ervin 所说的那样做了。

      1. 前端要求后端生成凭据
      2. 后端向前端发送凭据
      3. 前端上传文件到 S3
      4. 前端警告后端它已经完成。
      5. 后端验证一切是否正常。
      6. 后端会创建一个下载链接,您有很多安全选项。

      第 6 项示例)生成预签名 url 以下载内容。

          bucket = app.config.get('BOTO3_BUCKET', None)
          client = boto_flask.clients.get('s3')
      
          params = {}
          params['Bucket'] = bucket
          params['Key'] = attachment_model.s3_filename
          params['ResponseContentDisposition'] = 'attachment; filename={0}'.format(attachment_model.filename)
          if attachment_model.mimetype is not None:
              params['ResponseContentType'] = attachment_model.mimetype
      
          url = client.generate_presigned_url('get_object', ExpiresIn=3600, Params=params)
      
      

      第 2 项的示例)后端将创建预签名凭据以在 S3 上发布您的文件,将 s3_credentials 发送到前端

          acl_permission = 'private' if private_attachment else 'public-read'
          condition = [{'acl': acl_permission},
                       ["starts-with", "$key", '{0}/'.format(folder_name)],
                       {'Content-Type': mimetype }]
      
          bucket = app.config.get('BOTO3_BUCKET', None)
          fields = {"acl": acl_permission, 'Bucket': bucket, 'Content-Type': mimetype}
          client = boto_flask.clients.get('s3')
          s3_credentials = client.generate_presigned_post(bucket, s3_filename, Fields=fields, Conditions=condition, ExpiresIn=3600)
      

      第 5 项的示例)这是后端如何检查 S3 上的文件是否正常的示例。

          bucket = app.config.get('BOTO3_BUCKET', None)
          client = boto_flask.clients.get('s3')
          response = client.head_object(Bucket=bucket, Key=s3_filename)
          if response is None:
              return None, None
      
          md5 = response.get('ETag').replace('"', '')
          size = response.get('ContentLength')
      

      这里是前端如何请求凭据、将文件上传到 S3 并通知后端完成的示例。 我试图删除很多特定的代码。

      //frontend asking backend to create credentials, frontend will send some file metadata
      AttachmentService.createPostUrl(payload).then((responseCredentials) => {
          let form = new FormData();
          Object.keys(responseCredentials.s3.fields).forEach(key => {
            form.append(key, responseCredentials.s3.fields[key]);
          });
          form.append("file", file);
          let payload = {
              data: form,
              url: responseCredentials.s3.url
          }
          
          //Frontend will send file to S3
          axios.post(payload.url, payload.data).then((res) => {
            return Promise.resolve(true);
          }).then((result) => {
      
              //when it is done, frontend informs backend
              AttachmentService.uploadSuccess(...).then((refreshCase) => {
                  //Success 
              });
          });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        • 2018-03-08
        相关资源
        最近更新 更多