6

I am trying to upload data to an s3 bucket from the browser. I have generated a pre-signed url but I get a 403 forbidden response.

My server code is

const s3 = new AWS.S3({
  accessKeyId: settings.resourceBucketKey,
  secretAccessKey: settings.resourceBucketSecret,
  region: 'eu-west-1'
})

const params = {
  Bucket: 'my-bucket',
  Key: 'photo.png',
  ContentType: 'image/png',
  ACL: 'authenticated-read',
}

const url = s3.getSignedUrl('putObject', params)

console.log(url)

My client code is (using the generated url)

const input = $('#myinput')

      input.on('change', (res) => {
        var theFormFile = $('#myinput').get()[0].files[0];

        $.ajax({
          url: url,
          type: 'PUT',
          contentType: 'image/png',
          processData: false,
          data: theFormFile,
        }).success(function(){
          alert('success')
        })
      }, false)

I have set cors on on the bucket to:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

But I still get 403 forbidden on the response. The image I am trying to upload is call 'photo.png'. Am I missing something here?

2 Answers 2

5

The creator (you) of the pre-signed URL must have permissions to be able to access the S3 bucket to upload a file. This is more eloquently described in the S3 documentation:

A pre-signed URL gives you access to the object identified in the URL, provided that the creator of the pre-signed URL has permissions to access that object. That is, if you receive a pre-signed URL to upload an object, you can upload the object only if the creator of the pre-signed URL has the necessary permissions to upload that object.

Make sure the IAM user that is creating the pre-signed URL has the necessary permissions.

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

2 Comments

Thanks this was exactly the issue!
If it helps other wanderes. When this same is done via invoking Lambda functions, the function either should be invoked usng a IAM Role that that write & read access to S3, or it must contain access keys of a IAM user that has read & write access to S3. It may happen that the auto generated role which you chose during creation of Lambda function, not have required access to S3.
-5

Full implementation of getting signed url from browser - enjoy!

<body>
  <img height="200" width="200">
  <script>

    var mimes = {
        'jpeg': 'data:image/jpeg;base64,'
    };

      AWS.config.update({
          signatureVersion: 'v4',
          region: 'us-east-1',
          accessKeyId: '',
          secretAccessKey: ''
      });

      var bucket = new AWS.S3({params: {Bucket: 'xxxx'}});

      function encode(data)
      {
          var str = data.reduce(function(a,b){ return a+String.fromCharCode(b) },'');
          return btoa(str).replace(/.{76}(?=.)/g,'$&\n');
      }

      function getUrlByFileName(fileName,mimeType) {
          return new Promise(
              function (resolve, reject) {
                  bucket.getObject({Key: fileName}, function (err, file) {
                      var result =  mimeType + encode(file.Body);
                      resolve(result)
                  });
              }
          );
      }

      function openInNewTab(url) {
          var redirectWindow = window.open(url, '_blank');
          redirectWindow.location;
      }

      getUrlByFileName('sprites.png', mimes.jpeg).then(function(data) {
          //openInNewTab(data);
          document.querySelector('img').src = data;
      });

  </script>
</body>

2 Comments

don't forget to add - <script src="sdk.amazonaws.com/js/aws-sdk-2.179.0.min.js"></…>
I don't think is a good idea to put your secretAccessKey into client code

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.