Signatures signed S3 do not match

The name says it all. Here is my code;

I use node-formable for files.

form.on("end",function(field, file){ params.Body = fs.createReadStream(params.filePath) delete params.filePath; S3.getSignedUrl('putObject',params, function(err, url) { if(err){console.log(err);} console.log(url); }); }) 

After loading successfully, the url returns s3-url, something like this:

https://bucket-name.s3.amazonaws.com/746575308_8c081369df.jpg?AWSAccessKeyId=►key†&Expires=►date†&Signature=►signatureapter&x-amz-acl=public-read

But still, a SignatureDoesNotMatch error occurs. The description says

The signature we signed for the request does not match the signature you provided. Check your key and signature method.

Here are my options

 params = { Bucket:"bucketname", Key: file.name, ACL: 'public-read' } 

What am I missing?

+6
source share
2 answers

Give it a try. You need to load the object and then generate the signed URL against the existing object.

 var s3bucket = 'somebucket'; var s3Key = '/some/key', var body = fs.createReadStream('/some/local/file.txt'); var params = { Bucket: s3bucket, Key: s3Key, Body: body }; s3.upload(params, function(err) { if (err) { cb_1(err); } else { var params = { Bucket: s3bucket, Key: s3Key, Expires: parseInt(ttl) }; s3.getSignedUrl('getObject', params, function(err, url) { if (err) { console.log(err); } else { console.log(err); } }); } }); 
0
source

I ran into the same problem when using S3.getSignedUrl('putObject' , serveride, and then tried to use this client url.

What I noticed in my case, which may be relevant to yours, is that signatures created with all S3.getSignedUrl take into account request headers. Therefore, if you create a URL, it will crash with the same error message you received if not sent with the same headers.

One example of a failure: Generated as follows.

 var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000 }; s3.getSignedUrl('putObject', params, function (err, url) { if(err){ return cb(err); } return cb(null, url) }); 

The following request fails when using the same URL. This request was made from a browser.

 RequestMethod: Put Headers: { Accept:*/* Accept-Encoding:gzip, deflate, br Accept-Language:en-US,en;q=0.9 Connection:keep-alive Content-Length:11768 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 } 

And the difference is that the created signature does not contain the content type, where the request sets the content type. Params need to match the headers, or the error that you choose will not match the signature.

Successful example below:

 var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000, Content-Type: 'application/x-www-form-urlencoded; charset=UTF-8' }; s3.getSignedUrl('putObject', params, function (err, url) { if(err){ return cb(err); } return cb(null, url) }); 
0
source

Source: https://habr.com/ru/post/972049/


All Articles