【问题标题】:How can I use AWS Signature Version 4 with AWS Javascript SDK to upload to S3 from the browser?如何使用 AWS 签名版本 4 和 AWS Javascript 开发工具包从浏览器上传到 S3?
【发布时间】:2016-02-11 13:57:53
【问题描述】:

我需要能够从用户的浏览器将大 (1+ gb) 文件上传到 S3。由于大小和负载限制,通过应用程序服务器 (PHP) 发送它们根本不是一种选择。

我想使用 AWS Javascript SDK 来执行此操作,如下所示:http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Uploading_a_local_file_using_the_File_API

问题是,Javascript SDK 仅(官方)列出了几种身份验证方法,不清楚如何使 SDK 使用“AWS Signature V4”身份验证,如下所示:http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

问题是: 您可以将“Signature V4”与“AWS JS SDK”一起使用吗?

编辑:听起来我可能需要使用“安全令牌服务”:http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html 任何人都可以确认这是否是正确的方法吗?

可能相关的更多细节: 我的用例位于在线商店的管理区域,管理员用户已经通过登录管理部分进行了身份验证,但仍然不能看到主 AWS 密钥。 AWS JS SDK 允许您通过 Facebook 或其他 ID 提供商进行身份验证,但这将是一种奇怪的用户体验,因为管理员已经登录。

由于此功能必须打包到单个模块中才能安装在电子商务平台 (Magento) 中,因此要求安装程序同时使用单独的凭据创建一个新的 IAM 角色只是用于上传器功能是不可行的。

【问题讨论】:

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


    【解决方案1】:

    为已接受的答案添加更多信息,您可以参考我的博客以查看使用 AWS 签名版本 4 的代码运行版本。

    这里总结一下:

    用户选择要上传的文件后,立即执行以下操作:

    1. 调用 Web 服务器以启动服务以生成所需的参数

    2. 在该服务中,调用 AWS IAM 服务获取临时凭证

    3. 获得信任后,创建存储桶策略(base 64 编码字符串)。然后使用临时秘密访问密钥对存储桶策略进行签名以生成最终签名

    4. 将必要的参数发送回 UI

    5. 收到此信息后,创建一个 html 表单对象,设置所需的参数并发布它。

    详情请参考https://wordpress1763.wordpress.com/2016/10/03/browser-based-upload-aws-signature-version-4/

    【讨论】:

      【解决方案2】:

      要将文件从浏览器上传到 S3,您可以使用预签名 PUT。这样您就不会向浏览器泄露 aws 机密。您可以使用minio-js 库来生成预签名的 PUT url。

      在服务器端,您可以像这样生成预签名的 PUT url:

      var Minio = require('minio')
      
      // find out your s3 end point here:
      // http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
      
      var s3Client = new Minio({
          endPoint: 's3.amazonaws.com',
          accessKey: 'YOUR-ACCESSKEYID',
          secretKey: 'YOUR-SECRETACCESSKEY'
      })
      var presignedUrl = s3Client.presignedPutObject('bucket', 'object', 24*60*60)
      // presignedUrl expires in 1 day
      

      您可以将此预签名的 URL 传递给浏览器,该浏览器可以对 amazon s3 执行简单的 HTTP PUT。 PUT 请求将成功,因为签名将是 presignedUrl 的一部分。

      您也可以选择使用 presigned POST 来上传。

      【讨论】:

      • 如果我不能使用 AWS 开发工具包,您的解决方案似乎是下一个最优雅的解决方案。预签名 URL 是否仅适用于一个特定文件?如果是这样,这意味着它需要一个额外的 HTTP 请求来获取预签名的 url,然后才能实际进行上传。是否可以使用 AWS PHP SDK 来完成服务器端部分?不幸的是,我没有 node.js 服务器端,所以我只能使用 Minio-js 的客户端部分。我宁愿不滚动我自己的预签名密钥生成器代码。
      • @Eric - 另一种方法是 presignedPostPolicy - docs.aws.amazon.com/AmazonS3/latest/API/… github.com/minio/minio-js/blob/master/examples/… 通过您的 HTML 表单,您可以在已经预授权的预定义路径上传大量对象。
      • 我读过的所有内容都表明内容类型和对象键(又名文件名)是预签名 URL 的一部分。这意味着每个文件上传都需要一个新的预签名 URL,这意味着向应用程序服务器多发出一个 HTTP 请求(除了对 S3 的实际上传请求)。这也意味着我不能使用 AWS JS SDK,这将自动将上传分成更小的块,在网络错误时优雅地继续,提供文件上传进度事件等......我是否遗漏了什么或理解不正确?
      • @Eric 你是对的,每个文件上传都需要从应用服务器获取一个 presignedURL。
      【解决方案3】:

      您有 2 个选项,因为硬编码凭据从来都不是一个好的选择。

      1. 亚马逊认知
      2. Web 身份联合

      我建议您将适用于 JavaScript 的 AWS 开发工具包与 AWS Cognito 和开发人员身份验证一起使用。您提到的场景正是 Cognito 旨在解决的问题。您可以像现在一样让管理员使用您自己设计的身份验证方法登录系统,但使用该授权通过 Cognito 生成一个令牌,该令牌可用于对所有 AWS 服务进行身份验证。

      有关这两种情况的示例,请查看 AWS JavaScript 开发人员指南:在客户端浏览器中加载凭证:http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-configuring.html#Loading_Credentials_in_the_Client_s_Browser

      也可能对您有所帮助的参考资料:

      Amazon Cognito 开发者身份验证:http://docs.aws.amazon.com/cognito/devguide/identity/developer-authenticated-identities/

      身份提供者和联合:http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html

      适用于 JavaScript 的 AWS 开发工具包开发人员指南:http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/index.html

      【讨论】:

        猜你喜欢
        • 2013-11-06
        • 2017-08-29
        • 2023-03-15
        • 2016-01-15
        • 2014-11-16
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 2015-08-14
        相关资源
        最近更新 更多