4

I am using the aws-sdk to get a pre-signed url for S3. I have the function wrapped in a lambda.

const aws = require('aws-sdk');

module.exports = CreateRecord => {
  CreateRecord.controllers.createSignature = (event, context, callback) => {
    const s3 = new aws.S3({
      signatureVersion: 'v4',
    });

    const params = {
      Bucket: 'random-test-bucket002',
      Key: 'test-key',
      Expires: 100
    };

    s3.getSignedUrl('putObject', params, function(err, signedUrl) {
      let response;
      if (err) {
        response = {
          statusCode: 500,
          headers: {
            'Access-Control-Allow-Origin': '*',
          },
          body: JSON.stringify({
            error: 'Did not receive signed url'
          }),
        };
      } else {
        response = {
          statusCode: 200,
          headers: {
            'Access-Control-Allow-Origin': '*', // Required for CORS support to work
          },
          body: JSON.stringify({
            message: `Url successfully created`,
            signedUrl,
          })
        };
      }
      callback(null, response);
    });
  };
};

This code works perfectly fine and I get back my pre-signed url. When I run this code on my front end:

postImage(uuid) {
    const getSignature = 'https://xyz.execute-api.us-east-1.amazonaws.com/dev/v1/createSignature';
    axios.get(getSignature)
    .then(res => {
        const signatureUrl = res.data.signedUrl;
        // I have a blob that I store in file
        // uuid is passed from another function
        const file = new File([this.state.cover], uuid);

        axios.post(signatureUrl, file)
        .then(s3Res => {
            console.log(s3Res);
        });
    });
}

The error I keep getting is: The request signature we calculated does not match the signature you provided. Check your key and signing method. I tried messing around with a few content-type headers but that did nothing. Can I pass the pre-signed url to a function in the aws-sdk? I've looked at a lot of posts on this but can't seem to resolve the issue.

2
  • 2
    Try axios.put(...) to use HTTP PUT rather than POST. Commented Feb 23, 2018 at 0:56
  • Wow... that worked. Insane. Thank you so much!!! It seems like everywhere I was looking was using POST Commented Feb 23, 2018 at 0:59

1 Answer 1

3

When using pre-signed PutObject URLs for uploads to S3, you should upload files using the HTTP PUT method, rather than the HTTP POST method. You can POST objects to S3 but that's designed for browser-based uploads.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.