Reputation: 7607
My Request looks like this:
https://{my-bucket-name}.s3.amazonaws.com/{user-id}/{image-name}.jpeg?AWSAccessKeyId={key}&Content-Type=image%2Fjpeg&Expires=1597576628&Signature={signature}
where the {parts} are just censored but in the original response look correct, just like in a tutorial that I am doing.
I have allowed public access and set both CORS (which is why I get the pre-signed URL to upload to in the first place) as well as a bucket policy that contains this:
{
"Sid": "{sid}",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::{my-bucket-name}/*",
"Principal": "*"
}
So what might be the problem?
EDIT: adding PutObject to the policy did not help. I upload the file like this, from the React-client directly:
const upload = await axios.put(uploadConfig.data.url, file, {
headers: {
'Content-Type': file.type
}
})
And I generate the pre-signed URL like this (note the putObject operation):
s3.getSignedUrl('putObject', {
Bucket: '{my-bucket-name}',
ContentType: 'image/jpeg',
Key: key
}, (err, url) => res.send({key, url}));
Additional request headers set by the middleware/browser are:
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,de;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 104221
Content-Type: image/jpeg
Host: {my-bucket-name}.s3.amazonaws.com
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/blogs/new
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla....
Upvotes: 0
Views: 3856
Reputation: 8603
Please use AWS4-HMAC-SHA256.
error message suggests to use signature version v4. it appears the generated signature in the pre-signed url is not v4. possibly signature version v2
please try specifying the signature version when generating the URL as below.
const s3 = new AWS.S3({signatureVersion: 'v4'})
Also make sure that you are using aws-sdk version greater than 2.68.0
according to the documentation
Upvotes: 1