Pre-Signed S3 URL Signature Does Not Match
amazon-s3, amazon-web-services, node.js, pre-signed-url
Solution
I ran into the same problem while using `S3.getSignedUrl('putObject'`, serverside, and then trying to use that url clientside.
What I noticed in my case, which might be relevant to yours, is that signatures created with all the `S3.getSignedUrl` take into account request headers. So if you are generating a URL, it will fail with the same error message you received unless sent with the same headers.
One example of a failure: Generated like this..
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 a using that same url generated. 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 signature above created doesn't include content-type, where the request does specify a content-type. Params need to match headers, or the error thrown will be signature doesn't match.
Successful example below:
var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000, ContentType: 'application/x-www-form-urlencoded; charset=UTF-8' };
s3.getSignedUrl('putObject', params, function (err, url) {
if(err){
return cb(err);
}
return cb(null, url)
});
Problem
Title says everything. Here is my code; I'm using node-formidable 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 successful upload, url variable returns s3 url, something like this; https://bucket-name.s3.amazonaws.com/746575308_8c081369df.jpg?AWSAccessKeyId=[key]&Expires=[date]&Signature=[signature]&x-amz-acl=public-read But still getting SignatureDoesNotMatch error. In description says The request signature we calculated does not match the signature you provided. Check your key and signing method. Here is my parameters ``` params = { Bucket:"bucketname", Key: file.name, ACL: 'public-read' } ``` What am i missing?