You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:23:14