我尝试将jpeg图片上传到 s3存储桶,我成功获得预签名网址,没有任何错误,但在尝试上传jpeg图片时总是会收到错误使用该网址的图片。 错误:
<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网址后,尝试上传图片:
const options = {
headers: {
'Content-Type': File[0].type
}
};
axios.put(uploadURL, File[0], options);
我对Amazon 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"
}
}
}
]
}
Bucket 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>
更新: 当我尝试放置区域:'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 错误。
答案 0 :(得分: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'});