Rails中使用FineUploader的S3策略出错

时间:2017-02-18 06:56:59

标签: ruby-on-rails ruby amazon-s3 cors fine-uploader

我一直在尝试使用FineUploader JS库实现直接上传到S3。我在Rails中有一个后期操作,它构建并返回一个S3策略和签名,我尝试了很多不同的选项,但我在FineUploader中的策略一直出错。

这是我正在使用的FineUploader JS:

  <script>
    $('#fine-uploader-s3').fineUploaderS3({
        template: 'qq-template-s3',
        request: {
            endpoint: "https://mybucket.s3.amazonaws.com/",
            accessKey: MY_ACCESS_KEY
        },
        signature: {
            endpoint: "/generatesignature"
        },
       uploadSuccess: {
            endpoint: "/success",
            params: {
                isBrowserPreviewCapable: qq.supportedFeatures.imagePreviews
            }
        },
        iframeSupport: {
            localBlankPagePath: "/server/success.html"
        },
        cors: {
            expected: true
        },
        chunking: {
            enabled: true
        },
        resume: {
            enabled: true
        },
        deleteFile: {
            enabled: true,
            method: "POST",
            endpoint: "http://s3-demo.fineuploader.com/s3demo-thumbnails-cors.php"
        },
        validation: {
            itemLimit: 5,
            sizeLimit: 15000000
        },
        thumbnails: {
            placeholders: {
                notAvailablePath: "/plugins/fineuploader/placeholders/not_available-generic.png",
                waitingPath: "/plugins/fineuploader/placeholders/waiting-generic.png"
            }
        },
        callbacks: {
            onComplete: function(id, name, response) {
                var previewLink = qq(this.getItemByFileId(id)).getByClass('preview-link')[0];

                if (response.success) {
                    previewLink.setAttribute("href", response.tempLink)
                }
            }
        }
    });
</script>

以下是Ruby

中的generateignature action服务器端
  def generatesignature
  bucket = MY_BUCKET
  access_key = MY_ACCESS_KEY
  secret = MY_SECRET_KEY
  key = "test.txt/"
  expiration = 5.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z')
  max_filesize = 2.megabytes
  acl = 'public-read'
  sas = '200' # Tells amazon to redirect after success instead of returning xml
  policy = Base64.encode64(
    "{'expiration': '#{expiration}',
      'conditions': [
        {'bucket': '#{bucket}'},
        {'acl': '#{acl}'},
        {'Cache-Control': 'max-age=31536000'},
        ['starts-with', '$key', '#{key}'],
        ['content-length-range', 1, #{max_filesize}]
      ]}
    ").gsub(/\n|\r/, '')
  signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), secret, policy)).gsub(/\n| |\r/, '')
  {:access_key => access_key, :key => key, :policy => policy, :signature => signature, :sas => sas, :bucket => bucket, :acl => acl, :expiration => expiration}

params[:signature]= signature
params[:policy] = policy
render :json => params, :status => 200 and return
end

尝试上传到S3时收到的错误是: “根据政策无效:政策条件失败:[”eq“,”$ acl“,”public-read“]”

1 个答案:

答案 0 :(得分:0)

看起来好像是使用ACL值“public-read”生成签名,但默认情况下,Fine Uploader发送给S3的策略使用“私有”ACL。如果确实想要使用“公共读取”ACL,则需要更新objectProperties.acl Fine Uploader S3 configuration value。例如:

$('#fine-uploader-s3').fineUploaderS3({
  objectProperties: {
    acl: 'public-read'
  },
  ...
})