简体   繁体   English

如何使用后端预签名URL使用其SDK将文件上传到Amazon S3?

[英]How can i use a backend pre-signed url to upload files to Amazon S3 using its SDK?

I have a Rails backend and it returns to me a "signature" string, "objectKey" string and a "policy" string. 我有一个Rails后端,它返回给我一个“签名”字符串,“ objectKey”字符串和一个“策略”字符串。 I have to use these parameters to upload the file selected by the user, but i don't find any way to use these parameters instead of the "accessKey" and the "accessSecretKey" using the Amazon JavaScript SDK. 我必须使用这些参数来上传用户选择的文件,但是我找不到任何使用这些参数的方法,而不是使用Amazon JavaScript SDK的“ accessKey”和“ accessSecretKey”。

I already have a code that make the upload, but it is using the credentials directly, and it doesn't looks safe. 我已经有一个进行上传的代码,但是它直接使用了凭据,而且看起来不安全。

Anyone already faced this problem? 有人已经遇到这个问题了吗?

You can not upload an object with a presigned url. 您无法上传带有预签名网址的对象。 AWS has the solution in order to grant temporary credentials called AWS Security Token Service. AWS提供了一种解决方案来授予称为AWS安全令牌服务的临时凭证。 The short name is AWS STS. 简称为AWS STS。

Requesting Temporary Security Credentials - AWS Identity and Access Management 请求临时安全凭证-AWS Identity and Access Management

For examples: 举些例子:

  1. An user accesses to your rails application. 用户访问您的Rails应用程序。
  2. Your rails application issues and returns a temporary credentials using AWS STS. 您的rails应用程序将使用AWS STS发行并返回临时凭证。

     client = Aws::STS::Client.new policy = AWS::STS::Policy.new do |p| p.allow( actions: ['s3:PutObject'], resources: ['arn:aws:s3:::some-bucket/path/to/xxx*'], effect: 'allow' ) end token = client.get_federation_token(name: 'name', policy: policy.to_json, duration_seconds: 900) puts token.credentials.to_json # { # "access_key_id": "XXXXXXXXXXXXXXXXXXXX", # "secret_access_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", # "session_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", # "expiration": "2016-03-25T00:46:20Z" # } 
  3. The user upload an object securely using the temporary credentials. 用户使用临时凭据安全地上载对象。

Note that when you use the temporary credentials, you have to authenticate with access_key_id, secret_access_key and session_token . 请注意,使用临时凭证时,必须使用access_key_id,secret_access_key和session_token进行身份验证。

I did not found a solution for my problem with AWS Sdk for JavaScript. 找不到适用于JavaScript的AWS Sdk的问题的解决方案。

Looks that, in our case, the workflow(signature/policy generation) is the same of the shown in this article https://aws.amazon.com/articles/1434 看起来,在我们的例子中,工作流(签名/策略生成)与本文中显示的相同https://aws.amazon.com/articles/1434

To solve this problem I replaced the Sdk to a simple XmlHttpRequest and a FormData object to push my files to s3. 为了解决此问题,我将Sdk替换为简单的XmlHttpRequest和FormData对象,以将文件推送到s3。 The payload could not be changed to keep compatibility with another parts of the app. 有效负载无法更改以保持与应用程序其他部分的兼容性。 Using this approach it's necessary to have an AccessKey, policy, signature, key(file key) and the file in the formData. 使用这种方法,必须在formData中具有一个AccessKey,策略,签名,密钥(文件密钥)和文件。 Depending on how the policy/signature was generated, it's also necessary to add other fields to formData to get the things working. 根据策略/签名的生成方式,还需要向formData添加其他字段以使工作正常。 In this case, i've added a sucess_action_status. 在这种情况下,我添加了一个sucess_action_status。

The code to mount the formData: 挂载formData的代码:

  var formData = new FormData();
  formData.append('key', <KEY>);
  formData.append('AWSAccessKeyId', <ACCESS_KEY>);
  formData.append('policy', <POLICY>);
  formData.append('signature', <SIGNATURE>);
  formData.append('success_action_status', <SUCCESS_CODE>);
  formData.append('file', file, file.name);

With this form data, create a XMLHttpRequest like this 使用此表单数据,像这样创建XMLHttpRequest

var request = new XMLHttpRequest();
request.open("POST","https://<YOUR BUCKET>.s3.amazonaws.com");
request.setRequestHeader("enctype", "multipart/form-data");

And send the request passing the formData object. 并发送通过formData对象的请求。

request.send(formData);

It's important to remember that the values in formData must respect the generated policy. 重要的是要记住,formData中的值必须遵守生成的策略。

It's possible to get the upload process by adding this Listener: 可以通过添加以下监听器来获得上传过程:

request.upload.addEventListener('progress', function(e){
      console.log(e);
});

Thank you all for the help. 谢谢大家的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用我的签名证书生成预签名 URL 以在 Amazon S3 上提出异议 - How to use my signed-certificate to generate pre-signed URL to object at Amazon S3 如何使用 S3 预签名 POST url? - How to use an S3 pre-signed POST url? 如何使用预签名的 URL 而不是凭证直接从浏览器上传到 AWS S3? - How to upload to AWS S3 directly from browser using a pre-signed URL instead of credentials? 如何使用 angular 或 javascript 中的预签名 url 将文件上传到 S3 存储桶 - how to upload file to S3 bucket using pre-signed url in angular or javascript S3使用预先签名的URL从浏览器上传图片 - S3 Upload image with pre-signed url from browser 通过预签名URL将PUT上传到S3时拒绝签名 - Signature Denied in PUT upload to S3 with Pre-Signed URL 使用预签名 URL 将文件上传到 S3 - Uploading file to S3 using a pre-signed URL 如何在另一个选项卡中打开 S3 预签名 URL? - How to open an S3 pre-signed URL in another tab? 在我的 Angular 应用程序中使用 S3 预签名 url 下载多个文件 - Download multiple files using S3 pre-signed url in my Angular Application 如何使用签名的 URL 和 JavaScript 将二进制字符串文件上传到 Amazon S3? - How can I upload a file that is a binary string to Amazon S3 using a signed URL and JavaScript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM