12

I'm using Node to get an presignedRUL for S3 in order to PUT an image to an S3 bucket.

var aws = require('aws-sdk'); // Request presigned URL from S3 exports.S3presignedURL = function (req, res) { var s3 = new aws.S3(); var params = { Bucket: process.env.S3_BUCKET, Key: '123456', //TODO: creat unique S3 key //ACL:'public-read', ContentType: req.body['Content-Type'], //'image/jpg' }; s3.getSignedUrl('putObject', params, function(err, url) { if(err) console.log(err); res.json({url: url}); }); }; 

This successfully retrieves a presigned url of form...

https://[my-bucket-name].s3.amazonaws.com/1233456?AWSAccessKeyId=[My-ID]&Expires=1517063526&Signature=95eA00KkJnJAgxdzNNafGJ6GRLc%3D (Do I have to include an expires header?)

Back on the client side (web app) I use angular to generate an HTTP request. I have used both $http and ngFileUpload, with similar lack of success. Here is my ngFileUpload code.

Upload.upload({ url: responce.data.url, //S3 upload url including bucket name method: 'PUT', 'Content-Type': file.type, //I have tried putting the ContentTyep header all over headers: { //'x-amz-acl':'public-read', 'Content-Type': file.type, }, data: { file: file, headers:{'Content-Type': file.type,} }, }) 

However, seemingly regardless of how I format my header I always get a 403 error. In the XML of the error it says,

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

I don't think CORS is an issue. Originally I was getting some CORS errors but they looked different and I got them to go away with some changes to the S3 bucket CORS settings. I've tried a lot of trial and error setting of the headers for both the request for the presignedURL and PUT request to S3, but I can't seem to find the right combo.

I did notice that when I console.log the 403 response error, the field

config.headers:{Content-Type: undefined, __setXHR_: ƒ, Accept: "application/json, text/plain, */*"} 

Is this saying that the Content-Type head isn't set? How can that be when I've set that header everywhere I can think possible? Anyways, been banging my head against the wall of this for a bit...


EDIT: as requested, my Current CORS. (I threw everything in to get rid of the CORS warnings I had earlier. I will pare it down to the essentials only after I get my uploads working.)

<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedOrigin>http://localhost:9500</AllowedOrigin> <AllowedOrigin>https://localhost:9500</AllowedOrigin> <AllowedOrigin>http://www.example.com</AllowedOrigin> <AllowedOrigin>https://www.example.com</AllowedOrigin> <AllowedOrigin>http://lvh.me:9500</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <ExposeHeader>ETag</ExposeHeader> <AllowedHeader>*</AllowedHeader> <AllowedHeader>Content-Type</AllowedHeader> <AllowedHeader>Authorization</AllowedHeader> </CORSRule> </CORSConfiguration> 
6
  • You need more debug logging. Log the value of file.type, for example. Commented Jan 28, 2018 at 1:17
  • @Michael-sqlbot Yeah, I have logged everything but I took them out for sake of brevity in question. file.type logs "images/png" Commented Jan 28, 2018 at 22:02
  • Show your current bucket CORS configuration? Commented Jan 28, 2018 at 23:20
  • I am getting similar error. Did you figure out? Commented Mar 21, 2018 at 2:42
  • I did not. Please let me know if you do. Commented Mar 21, 2018 at 11:03

2 Answers 2

6

Faced the same issue. Found out that the content-type that I used to create the pre-signed URL was not matching the content-type of the object I was sending to S3. I would suggest you add Expiration header when creating the pre-signed URL (I did too) and check in the console exactly what the content-type is being sent when you do a put to S3. Also, the data just needs to be the file, and not the struct you've created there.

Sign up to request clarification or add additional context in comments.

Comments

0

I was having 403 errors with signature not matching and for the life of me could not figure out why. Reading some other examples one of them said it had to be run in us-east-1 because it was not supported in other regions. I was in us-east-2, switched and same exact code worked.

Try using us-east-1

1 Comment

It is strange only work in one particular region, has anyone had similar experience?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.