1
votes

I am trying to upload an image using presigned url

const s3Params = {
  Bucket: config.MAIN_BUCKET,
  Key: S3_BUCKET + '/'+fileName,
  ContentType: fileType,
  Expires: 900,
  ACL: 'public-read'
};
const s3 = new AWS.S3({
  accessKeyId: config.accessKeyId,
  secretAccessKey: config.secretAccessKey,
  'region': config.region
});
const url = await s3.getSignedUrlPromise('putObject', s3Params)
return url

i get a url something like

https://s3.eu-west-1.amazonaws.com/bucket/folder/access.JPG?AWSAccessKeyId=xxxx&Content-Type=multipart%2Fform-data&Expires=1580890085&Signature=xxxx&x-amz-acl=public-read

  1. i have tried uploading file with content type image/jpg, multipart/form-data.
  2. Tried generating url without filetype and upload.
  3. tried put and post method

but nothing seems to work

Error always :

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

Access credentials have appropriate permissions because these upload files fine when trying though s3 putobject upload (though api instead of presigned url)

Edit:

It seems that postman is sending content-type as multipart/form-data; boundary=--------------------------336459561795502380899802. here boundary is added extra. how to fix this?

2
please post the client code that uploads the imageArun K
try ContentType: 'application/octet-stream' when generating the url, and pass the same content-type when uploading.Arun K

2 Answers

1
votes

As per the AWS S3 documentation Signing and Authenticating REST request, S3 is using SignatureVersion4 by default.

But the nodejs AWS-SDK is using SignatureVersion2 by default.

So you have to explicitly specify SignatureVersion4 in request header

Add this code in S3 config

    s3 = new AWS.S3({
        'signatureVersion':'v4'
    });
0
votes

I was testing through form-data on postman. but getsignedUrl() function does not support that. Tried using binary and it worked fine. For multipart there seems to be a different function in aws sdk