我正在尝试使用HTML POST表单和上传策略执行上传到S3,并且我正在努力创建签名以与其一起使用。
当我提交上传表单时,我一直收到403和SignatureDoesNotMatch回复。
以此为指导,http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html我想出了以下内容:
policy_hash = {
'expiration' => (Time.now.utc + 3600 * 3).iso8601
}
@policy = Base64.encode64(JSON.dump(policy_hash)).gsub("\n","")
kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + @secret_access_key, Time.now.strftime("%Y%m%d"))
kRegion = OpenSSL::HMAC.digest('sha256', kDate, AWS_REGION)
kService = OpenSSL::HMAC.digest('sha256', kRegion, "s3")
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
@signature = Digest::SHA256.hexdigest(
OpenSSL::HMAC.digest('sha256', kSigning, @policy)
)
我将政策和签名包括在内。我知道AWS_REGION
和@secret_access_key
是正确的,因为我在其他地方使用它们。
任何人都可以看到上面的代码有什么问题吗?或有任何其他指导?
答案 0 :(得分:0)
@signature = Digest::SHA256.hexdigest(
OpenSSL::HMAC.digest('sha256', kSigning, @policy)
)
你正在采取你的签名,而不是十六进制编码,你用SHA256和十六进制编码哈希对它进行哈希。
我不是一个红宝石的人,但这里有一个猜测你真正需要的东西:
@signature = OpenSSL::HMAC.hexdigest('sha256', kSigning, @policy)
答案 1 :(得分:0)
更新可以帮助将来的任何人,我最终使用aws-sdk gem为我处理所有的签名和表单构建。
@s3_base_path = "#{SecureRandom.uuid}/"
creds = Aws::Credentials.new(access_key_id, secret_access_key, session_token)
@post = Aws::S3::PresignedPost.new(creds.credentials, AWS_REGION, S3_BRANDING_FILES_BUCKET, {
key_starts_with: @s3_base_path,
acl: 'private',
success_action_status: '201',
server_side_encryption: 'AES256',
signature_expiration: Time.now.utc + 3600 * 3
})
然后在视图中:
<!-- Direct Upload to S3 Form -->
<form action="<%= @post.url %>" method="POST" enctype="multipart/form-data">
<% @post.fields.each do |name, value| %>
<input type="hidden" name="<%= name %>" value="<%= value %>"/>
<% end %>
<!-- Key is the file's name on S3 and will be filled in with JS -->
<input type="hidden" name="key" value="">
<div class="hiddenfile" style="height:0; width:0; overflow:hidden;">
<input type="file" accept="image/gif, image/jpeg" name="file" id="file-input">
</div>
</form>