1

Using aws-sdk.js with NodeJs.

Generated a signed URL for file upload (putObject) to a AWS bucket, along with file download (getObject) signed URL.

File download URL is working, however upload URL is throwing error:

<?xml version="1.0" encoding="UTF-8"?>

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AWSACCESSKEY</AWSAccessKeyId></Error>

JS to generate signed URL for getObject and putObject:

var AWS = require('aws-sdk');
// AWS is configured in .aws and is correct 
const s3 = new AWS.S3();

var params = {
    Bucket: 'upload-bucket',
    Key: 'Account_Info.pdf',
    Expires: 60*60
};

// Upload signedUrl
let putUrl = s3.getSignedUrl('putObject', params);
console.log("Put: ", putUrl);

let p = JSON.parse(JSON.stringify(params));
p.Key= 'Account.pdf';
// download signed Url
let url = s3.getSignedUrl('getObject', p);

signed URL for download is working fine, need to know what might be wrong in put API.

JS code for upload file:

let request = require('request');
var fs = require("fs");

let file = new Buffer(fs.readFileSync('Account_Info.pdf', 'base64'), 'base64');

let url = putUrl; //'something/Account_Info.pdf';
let method = 'PUT';
let qs = {
  'AWSAccessKeyId': 'AWSACCESSKEY',
  'Expires':'1539258230',
  'Signature':'Qbuu9fP6rrmwWDAPQFf%2BE3JiGZo%3D'
};

let formData = {
  file: { value: file,
    options: { filename: 'Account_Info.pdf', contentType: 'pdf' } }
};

let ops = {
  url, method, qs, formData
};

request (ops, (err, res, body) => {
  console.log(err);
  console.log(body);
});

Is error due to conversion of all special character to their utf-8 notation like all = become %2D, / become %2F, + become %2B. However tried converting them back to actual form didn't work and more over this doesn't seems to affect GET URL. Tried passing qs along URL no change in result.

Wasted 3 days figuring out what might be going wrong here. Wish AWS error would been more clear, and AWS would had provided better documentation for file upload.

Any help is needed.

NAVIN
  • 3,193
  • 4
  • 19
  • 32
  • Possible duplicate of [AWS S3 Generating Signed Urls ''AccessDenied''](https://stackoverflow.com/questions/52667434/aws-s3-generating-signed-urls-accessdenied) – Reza Mousavi Oct 11 '18 at 12:29
  • @RezaMousavi Mine is different. My `getObject` API is working. I need to know why PUT API `putObject` is throwing error when get is working? – NAVIN Oct 11 '18 at 15:33
  • The short answer is the request you *proposed* (to s3.getSignedUrl) when you created the signed URL does not match the request you *generated* in JS. `SignatureDoesNotMatch` means the signature is wrong for the request S3 received, but the one-way nature of the hmac-sha signature algorithm makes it impossible for the service to actually know why -- that's why it doesn't tell you, because it can't. Among the apparent issues: `formData` has no place in a `PUT` request, and you should be specifying a Content-Type both in the params of getSignedUrl as well as when you actually make the request. – Michael - sqlbot Oct 12 '18 at 09:26

0 Answers0