S3使用预先签名的URL从浏览器上传图片

时间:2016-09-16 16:46:32

标签: javascript amazon-s3

我正在尝试从浏览器将数据上传到s3存储桶。我已经生成了一个预先签名的网址,但我收到了403禁止回复。

我的服务器代码是

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)

我的客户端代码是(使用生成的网址)

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)

我已经在战斗中设置了角色:

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

但我仍然拒绝回复403。我要上传的图片是“photo.png”。我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:1)

预签名URL的创建者(您)必须具有访问S3存储桶以上载文件的权限。这在S3 documentation中更加雄辩地描述:

  

预先签名的网址可让您访问网址中标识的对象,   前提是预签名URL的创建者具有权限   访问该对象。也就是说,如果您收到要上传的预签名网址   一个对象,只有在创建者时才能上传对象   预签名URL具有上传该对象的必要权限。

确保创建预签名URL的IAM用户具有必要的权限。

答案 1 :(得分:-1)

从浏览器中获取签名网址的全面实施 - 享受!

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