尝试从客户端上传时,我总是收到403。这是由于没有条件在桶上?如果我只是指定密钥 - 没有accesskey,签名或策略 - 它会正常上传。用rails,carrierwave-direct和jquery文件上传将文件上传到客户端的s3
桶政策:
{
"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);
}
});
我在过去做过。我正在关注Heroku的这篇文章。 https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails你也可以参考http://stackoverflow.com/a/34830257/3962760答案相同。 –
刚达到文档。它看起来非常好。我会在早上通过它。谢谢。另外,你知道为什么s3允许我上传没有认证的文件吗?这是缺少的政策条件吗? –
基本的东西是CORS设置和S3存储桶对象具有正确的凭据。如果这两件事情是适当的,那么你可以很容易地获得你的预先签名的URL。一旦你有了,那么没有其他认证需要。 –