我有一个Rails后端,它返回给我一个“签名”字符串,“objectKey”字符串和一个“策略”字符串。我必须使用这些参数来上传用户选择的文件,但我找不到任何方法来使用这些参数而不是使用Amazon JavaScript SDK的“accessKey”和“accessSecretKey”。
我已经有一个代码可以进行上传,但它直接使用了凭据,而且看起来并不安全。
任何人都已经遇到过这个问题?
答案 0 :(得分:0)
您无法使用预先签名的网址上传对象。 AWS拥有解决方案,以便授予名为AWS Security Token Service的临时凭证。简称AWS STS。
Requesting Temporary Security Credentials - AWS Identity and Access Management
例如:
您的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"
# }
用户使用临时凭证安全地上传对象。
请注意,当您使用临时凭证时,您必须使用access_key_id,secret_access_key和 session_token 进行身份验证。
答案 1 :(得分:0)
我没有找到解决我的AWS Sdk for JavaScript问题的解决方案。
在我们的案例中,看起来工作流程(签名/策略生成)与本文https://aws.amazon.com/articles/1434中显示的相同
为了解决这个问题,我将Sdk替换为一个简单的XmlHttpRequest和一个FormData对象,将我的文件推送到s3。无法更改有效负载以保持与应用程序的其他部分的兼容性。使用此方法,必须在formData中具有AccessKey,策略,签名,密钥(文件密钥)和文件。根据策略/签名的生成方式,还需要向formData添加其他字段以使事情正常工作。在这种情况下,我添加了一个sucess_action_status。
安装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);
使用此表单数据,像这样创建XMLHttpRequest
var request = new XMLHttpRequest();
request.open("POST","https://<YOUR BUCKET>.s3.amazonaws.com");
request.setRequestHeader("enctype", "multipart/form-data");
并发送传递formData对象的请求。
request.send(formData);
重要的是要记住formData中的值必须遵守生成的策略。
可以通过添加此Listener来获取上传过程:
request.upload.addEventListener('progress', function(e){
console.log(e);
});
谢谢大家的帮助。