问题
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?
回答1:
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, 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)
});
回答2:
Give this a try. You need to upload the object, then generate the signed url against an 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);
}
});
}
});
来源:https://stackoverflow.com/questions/24684959/pre-signed-s3-url-signature-does-not-match