クライアント側からアップロードしようとすると、403が表示され続けます。バケツに条件がないためですか?アクセスキー、署名、ポリシーなしでキーを指定するだけで、うまくアップロードできます。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バケットオブジェクトです。これらの2つのことが適切であれば、事前に署名されたURLを簡単に取得できます。そして一度あなたがそれを持っていれば、他の認証は必要ありません。 –