当前位置: 首页 > 知识库问答 >
问题:

上传文件到s3在客户端与rails,CarrierWav-Direct和jQuery文件上传

龚同
2023-03-14

当我试图从客户端上传时,我一直得到403。这是因为桶上没有条件吗?如果我只是指定密钥-没有访问密钥,签名或策略-它将上传罚款。

桶策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::example/*"
        }
    ]
}

CORS(因当地开发而开放)

<?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>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

签名生成

    ///whats returned - in controller

    string_to_sign
    set_s3_direct_post(photo)
    render :json => {
        :policy => @policy,
        :signature => sig,
        :key => Rails.application.secrets.aws_access_key_id,
        :success=>true,
        :store=> photo.photo.store_dir,
        :time => @time_policy,
        :time_date => @date_stamp,
        :form_data => @s3_direct_post
    }

 ------------------------------------------------------------------
    private

   def string_to_sign
     @time = Time.now.utc
     @time_policy = @time.strftime('%Y%m%dT000000Z')
     @date_stamp = @time.strftime('%Y%m%d')

     ret = {"expiration" => 1.day.from_now.utc.xmlschema,
            "conditions" =>  [
                {"bucket" => Rails.application.secrets.aws_bucket},
                {"x-amz-credential": "#{Rails.application.secrets.aws_access_key_id}/#{@date_stamp}/us-west-2/s3/aws4_request"},
                {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
                {"x-amz-date": @time_policy },
            ]
            }

      @policy = Base64.encode64(ret.to_json).gsub(/\n/,'').gsub(/\r/,'')

    end

    def getSignatureKey
        kDate = OpenSSL::HMAC.digest('sha256', ("AWS4" +  Rails.application.secrets.aws_secret_access_key), @date_stamp)
        kRegion = OpenSSL::HMAC.digest('sha256', kDate, 'us-west-2')
        kService = OpenSSL::HMAC.digest('sha256', kRegion, 's3')
        kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
    end

    def sig
       sig = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), getSignatureKey, @policy).gsub(/\n|\r/, '')
    end

客户:

    var self=this;
    $(`#song-upload`).fileupload({
        url: `https://${self._backend.BUCKET}.s3.amazonaws.com`,
        dataType: 'json',
        add: function (e, data) {
          var data_add = data;
          $.ajax({
            url: `${self._backend.SERVER_URL}/api/photo/new`,
            data: {'authorization': `Bearer ${self._auth.isLoggedIn.getCookie('_auth')}`, post_type: 1, file_name:this.file_name},
            type: 'POST',
            success: function(data) {
              if(data.success){
                console.log(data);
                self.key = data.key;
                self.policy = data.policy;
                self.signature = data.signature;
                self.store_dir = data.store;
                self.upload_time = data.time;
                self.upload_date = data.time_date;
                data_add.submit();
               }
            }
          });
        },
        submit: function (e, data) {
          data.formData = {key:`${self.store_dir}/${self.file_name}`,AWSAccessKeyId: self.key, "Policy":self.policy, "x-amz-algorithm":"AWS4-HMAC-SHA256","Signature":self.signature,"x-amz-credential":`${self.key}/${self.upload_date}/us-west-2/s3/aws4_request`, "x-amz-date":self.upload_time};
        },
        progress: function (e, data) {
          var progress = Math.floor(((parseInt(data.loaded)*0.9)  / (parseInt(data.total))) * 100);
          $('#inner-progress').css({'transform':`translateX(${progress}%)`});
          $('#progress-text').text(progress);
        },
        done: function (e, data) {
            $('#inner-progress').css({'transform':`translateX(100%)`});
            $('#progress-text').text(100);
            if(e) console.log(e);
        }
    });

共有1个答案

方浩旷
2023-03-14

如果有人有此功能,并且正在尝试进行javascript上载,请尝试将这些值插入到此处找到的html文件中。Amazon将告诉您实际的错误,而不仅仅是403响应。

我错过了[启动,$key,上传]在我的bas64d配置。

这是我的最终配置:

桶配置:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow Get",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example-development/*"
        },
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789:user/example"
            },
            "Action": "s3:*",
            "Resource": ["arn:aws:s3:::example-development/*","arn:aws:s3:::example-development"]
        }
    ]
}

水桶

<?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>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

后端:

       string_to_sign
       set_s3_direct_post(song)
       render :json => {
                :policy => @policy,
                :signature => sig,
                :key => Rails.application.secrets.aws_access_key_id,
                :success=>true,
                :store=> song.song.store_dir,
                :time => @time_policy,
                :time_date => @date_stamp,
                :form_data => @s3_direct_post
       }

def string_to_sign

    @time = Time.now.utc
    @time_policy = @time.strftime('%Y%m%dT000000Z')
    @date_stamp = @time.strftime('%Y%m%d')

     ret = {"expiration" => 10.hours.from_now.utc.iso8601,
            "conditions" =>  [
                {"bucket" => 'waydope-development'},
                {"x-amz-credential": "#{Rails.application.secrets.aws_access_key_id}/#{@date_stamp}/us-west-2/s3/aws4_request"},
                {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
                {"x-amz-date": @time_policy },
                ["starts-with", "$key", "uploads"]
            ]
            }
    @policy = Base64.encode64(ret.to_json).gsub(/\n|\r/, '')

end

def getSignatureKey
        kDate = OpenSSL::HMAC.digest('sha256', ("AWS4" +  Rails.application.secrets.aws_secret_access_key), @date_stamp)
        kRegion = OpenSSL::HMAC.digest('sha256', kDate, 'us-west-2')
        kService = OpenSSL::HMAC.digest('sha256', kRegion, 's3')
        kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
    end

def sig
        # sig = Base64.encode64(OpenSSL::HMAC.digest('sha256', getSignatureKey,  @policy)).gsub(/\n|\r/, '')
        sig = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), getSignatureKey, @policy).gsub(/\n|\r/, '')
end

客户:

var self=this;
    $(`#song-upload`).fileupload({
        url: `https://${self._backend.BUCKET}.s3.amazonaws.com`,
        dataType: 'multipart/form-data',
        add: function (e, data) {
          var data_add = data;
          $.ajax({
            url: `${self._backend.SERVER_URL}/api/music/new`,
            data: {'authorization': `Bearer ${self._auth.isLoggedIn.getCookie('_waydope')}`, post_type: 1, file_name:this.file_name},
            type: 'POST',
            success: function(data) {
              if(data.success){
                console.log(data);
                self.key = data.key;
                self.policy = data.policy;
                self.signature = data.signature;
                self.store_dir = data.store;
                self.upload_time = data.time;
                self.upload_date = data.time_date;
                data_add.submit();
               }
            }
          });
        },
        submit: function (e, data) {
          data.formData = {key:`${self.store_dir}/${self.file_name}`, "Policy":self.policy,"X-Amz-Signature":self.signature,"X-Amz-Credential":`${self.key}/${self.upload_date}/us-west-2/s3/aws4_request`,"X-Amz-Algorithm":"AWS4-HMAC-SHA256", "X-Amz-Date":self.upload_time, "acl": "public-read"};
        },
        progress: function (e, data) {
          var progress = Math.floor(((parseInt(data.loaded)*0.9)  / (parseInt(data.total))) * 100);
          $('#inner-progress').css({'transform':`translateX(${progress}%)`});
          $('#progress-text').text(progress);
        },
        done: function (e, data) {
            $('#inner-progress').css({'transform':`translateX(100%)`});
            $('#progress-text').text(100);
            if(e) console.log(e);
        }
    });
 类似资料:
  • 我正在尝试使用jQuery文件上传和aws sdk gem在Rails中实现直接到AmazonS3上传,并遵循heroku的直接到S3上传说明。这是在html中生成的上载表单: 这是相应的jQuery: 尝试上传文件会产生以下日志: 表单提交成功,但由于Rails没有在S3上保存正确的位置(“picture”,一个字符串),表单无法工作;相反,它认为地点是 您可以在提交的参数中看到这一点。应该是这

  • 问题内容: 首先,我通常不愿发布这个问题,因为我一直觉得互联网上的所有内容都有答案。在花了无数小时寻找这个问题的答案之后,我终于放弃了这个声明。 这有效: 我想做什么? 使用getSignedUrl方法通过PUT(从客户端)将文件上传到Amazon S3 允许任何人查看上载到S3的文件 注意: 如果有一种更简便的方法允许客户端(iPhone)使用预签名的URL(并且不暴露客户端的凭据)将其上传到A

  • 我肯定在这里缺少某种序列化程序 任何建议都将不胜感激! 谢谢

  • 本文向大家介绍Java下http下载文件客户端和上传文件客户端实例代码,包括了Java下http下载文件客户端和上传文件客户端实例代码的使用技巧和注意事项,需要的朋友参考一下 一、下载客户端代码 上述代码只适合下载小文件,如果下载大文件则会出现  Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 错误,所以

  • 以下是AWS Amplify GraphQL客户端的官方文档:https://aws-amplify.github.io/amplify-js/media/api_guide.html.本节提供了基本输入的示例。 对于AWS Mobile Appsync SDK For Javascript,这里有一个详细的文档:https://docs.aws.amazon.com/appsync/latest

  • 我有一个单页应用程序,前端部分使用ReactJS和MobX构建,后端部分使用ruby-on-rails构建。我有一个图像放置区域容器,我希望用户能够上载图像,但所有上载实现都要在前端完成,后端只会收到上载图像的URL。有没有可能在根本不涉及服务器的情况下使用ReactJS实现这一点?