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...