I try to upload jpeg image to the s3 bucket, I get Pre-sign URL successfully without any error but I always get the errors when I try to upload an image using that URL. Errors:
<Code>AuthorizationQueryParametersError</Code>
<Message>
Error parsing the X-Amz-Credential parameter; the region 'us-east-1' is wrong; expecting 'eu-west-1'
</Message>
I will explain steps how I did that:
1.Get presign url:
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 });
}
})
});
After I get my Presighn URL I try to upload my image:
const options = {
headers: {
'Content-Type': File[0].type
}
};
axios.put(uploadURL, File[0], options);
My bucket policy on 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 Configuration:
<?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>
Update: When I try to put the region:'eu-west-1' it give me another error said:
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
Update V2: I know where is the problem but I don't know why that happened, When I use pre_sign URL without login by passport everything going correct but when I log in using passport JWT I get SignatureDoesNotMatch error.
I faced the same issue. It seems to be a very popular issue of AWS sdk version 1. I believe your s3 bucket has been assigned the region 'eu-west-1'.
It happens to be that 'eu-west-1' requires AWS version 4 signature and when you evaluate the signature from the signed Url, the region set while making the call, becomes the part of the signature string.
Here's the tricky part, when you directly make the call using endpoint 's3.amazonaws.com', the sdk does not know the reason to be used, and thus user any random region. In your case 'us-east-1', which does not match you bucket region and thus violates the version 4 signature.
The solution that I used, was to simply mention the region in s3 options, and may or may not mention signture version. Since anyways, the SDK would automatically set the signature version optimal for the region.