使用STS临时凭证生成预签名URL上传S3遇问题求助
S3浏览器上传:AssumeRole预签名URL的问题
错误信息
return (<Code>InvalidAccessKeyId</Code> )return (<Message>The AWS Access Key Id you provided does not exist in our records.</Message> )
方法1:POST预签名表单上传(触发错误)
后端生成预签名表单代码
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,仍会触发上述InvalidAccessKeyId错误。
方法2:PUT预签名URL上传(文件解析异常)
后端生成预签名URL代码
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); });
说明:该方法可成功完成上传,但下载后的.xxx文件无法正常解析(测试PDF、PNG等格式可正常打开),推测是此方法下S3修改了文件的签名/哈希导致。而使用方法1和IAM用户凭证上传时无此问题。
疑问
是否存在无需使用IAM用户凭证,直接从浏览器向S3上传文件的其他可行方法?
内容的提问来源于stack exchange,提问作者sgk
相关产品推荐
相关产品推荐

