0

我尝试将 jpeg 图像上传到s3 存储桶,我成功获得了预签名 URL,没有任何错误,但是当我尝试使用该 URL 上传图像时,我总是得到错误。错误:

 <Code>AuthorizationQueryParametersError</Code>
    <Message>
    Error parsing the X-Amz-Credential parameter; the region 'us-east-1' is wrong; expecting 'eu-west-1'
    </Message>

我将解释我是如何做到这一点的步骤:

1.获取签名网址:

const s3 = new AWS.S3();
s3.config.update({
  accessKeyId: keys.accessKeyId,
  secretAcccessKey: keys.secretAcccessKey,
  signatureVersion: 'v4',
});
router.get('/', (req, res) => {
    const key = '123.jpeg';
    s3.getSignedUrl(
      'putObject', {
        Bucket: 'My bucket',
        ContentType: 'image/jpeg',
        Key: key,
        Expires: 1000
      },
      (e, url) => {
        if (e) {
          res.status(400).json(errors);
        } else {
          res.json({ url, key });
        }
      })
  });

获得 Presighn URL 后,我尝试上传我的图片:

const options = {
        headers: {
          'Content-Type': File[0].type
        }
      };
      axios.put(uploadURL, File[0], options);

我在亚马逊 s3 上的存储桶策略:

{
    "Version": "2012-10-17",
    "Id": "Policy17794",
    "Statement": [
        {
            "Sid": "damy",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::backetName/*",
            "Condition": {
                "NumericGreaterThan": {
                    "s3:signatureAge": "600000"
                }
            }
        }
    ]
}

桶 Cors 配置:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

更新: 当我尝试输入region:'eu-west-1'时,它给了我另一个错误说:

<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>

更新 V2:我知道问题出在哪里,但我不知道为什么会这样,当我使用 pre_sign URL 而不通过护照登录时,一切正常,但是当我使用护照 JWT 登录时,我收到SignatureDoesNotMatch错误。

4

1 回答 1

0

我遇到了同样的问题。这似乎是 AWS sdk 版本 1 的一个非常受欢迎的问题。我相信您的 s3 存储桶已分配到区域“eu-west-1”。

恰好“eu-west-1”需要 AWS 版本 4 签名,当您从签名的 Url 评估签名时,进行调用时设置的区域成为签名字符串的一部分。

这是棘手的部分,当您直接使用端点“s3.amazonaws.com”进行调用时,sdk 不知道要使用的原因,因此使用任何随机区域。在您的情况下,“us-east-1”与您的存储桶区域不匹配,因此违反了版本 4 签名。

我使用的解决方案是在 s3 选项中简单地提及该区域,并且可能会或可能不会提及签名版本。无论如何,SDK 会自动为该地区设置最佳的签名版本。

    let s3 = new AWS.S3({region: 'us-east-1'});
于 2019-04-02T08:10:28.010 回答