我正在尝试使用预签名的URL将文件上传到s3。我可以使用AssumeRole凭据成功生成URL,但从浏览器上传文件时,它抛出以下错误。
<Code>InvalidAccessKeyId</Code>
<Message>The AWS Access Key Id you provided does not exist in our records.</Message>
方法一:
用于生成预签名URL的代码
cred = Aws::AssumeRoleCredentials.new(role_arn: ENV['AWS_ROLE_ARN'], role_session_name: 'xxx_service').credentials
post = Aws::S3::PresignedPost.new(creds, S3_REGION, S3_BUCKET, {
key: Rails.env + '/' + file_name,
metadata: {
'original-filename' => file_name
},
acl: 'private',
})
url = post.url,
fields = post.fields
从浏览器上传文件的前端代码
var form = new FormData();
form.append("key", "demo/test.xxx");
form.append("x-amz-meta-original-filename", "test.xxx");
form.append("policy", "XXXXXX");
form.append("x-amz-credential", "AXXXXXXX");
form.append("x-amz-algorithm", "AWS4-HMAC-SHA256");
form.append("x-amz-date", "20230530T145924Z");
form.append("x-amz-signature", "4XXXXXXXXXXXXXXX");
form.append("file", fileInput.files[0], "test.xxx");
form.append("x-amz-security-token", "IQXXXXXXXXXXX");
var settings = {
"url": "https://bucket-url",
"method": "POST",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});
使用IAM用户凭据时也可以使用相同的代码。由于网络安全要求,我们已开始使用AssumeRole凭据。甚至我尝试在请求体中添加x-amz-session-token
,但输出没有任何差异。
后来我发现了另一种生成预签名URL的方法,它允许我使用PUT方法从Brower成功上传文件。
方法二:
signer = Aws::S3::Presigner.new(credentails: creds, region: S3_REGION)
url, _ = signer.presigned_request(
:put_object, bucket: S3_BUCKET, key: "#{Rails.env}/#{file_name}"
)
从浏览器上传文件的前端代码
var form = new FormData();
form.append("file", fileInput.files[0], "test.xxx");
var settings = {
"url": "https://bucket-url/demo/Sunspot.xxx?X-Amz-Algorithm=XXXXX&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Credential=XXXXX&X-Amz-Date=20230530T144029Z&X-Amz-Security-Token=XXXXX%3",
"method": "PUT",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});
上述解决方案的唯一问题是我无法从S3下载文件**.xxx后重新解析它。我已经通过上传PDF和PNG图像测试了这个解决方案,下载后它可以正常打开。也许S3在第二种方法中修改了文件.xxx**的签名/散列,因此我无法重新解析该文件。使用第一种方法和IAM凭据,它工作正常。
是否有其他方法可以不使用IAM用户凭据而直接从浏览器将文件上传到S3?
2条答案
按热度按时间guykilcj1#
如果通过 reparse 你引用的文件再次从S3存储桶中获取它,我认为你需要使用预签名的URL来获取它:
然后,您只需从该URL获取文件,并根据需要对其进行转换。
UPDATE:使用
ChunkyPNG
按需转换镜像:300.seconds
可能是特定于轨道的,我不确定您是否在使用,但这就是我们的想法。nvbavucw2#
我可以使用预签名POST机制本身上传文件。在前端代码中更改表单数据的顺序对我来说很有效。AWS错误消息具有误导性,它不是要求我们以正确的顺序发送安全字段,而是告诉我们AccessKEY未找到。我只是交换了
x-amz-signature
和x-amz-security-token
的位置工作码
我们需要在上传文件到S3时以正确的顺序发送安全字段。
我从here找到了这个