gpt4 book ai didi

ruby-on-rails - 尝试生成预先签名的 url 链接,以便用户可以下载 Amazon S3 对象,但收到无效请求

转载 作者:行者123 更新时间:2023-12-03 17:06:46 26 4
gpt4 key购买 nike

我目前正在使用带有服务器端客户提供的加密 key (SSE-C) 的 Ruby aws-sdk 版本 2 gem。我可以毫无问题地将对象从 rails 表单上传到 Amazon S3。

def s3
Aws::S3::Object.new(
bucket_name: ENV['S3_BUCKET'],
key: 'hello',
)
end

def upload_object
customer_key = OpenSSL::Cipher::AES.new(256, :CBC).random_key
customer_key_md5 = Digest::MD5.new.digest(customer_key)
object_key = 'hello'
options = {}
options[:key] = object_key
options[:sse_customer_algorithm] = 'AES256'
options[:sse_customer_key] = customer_key
options[:sse_customer_key_md5] = customer_key_md5
options[:body] = 'hello world'
options[:bucket] = ENV['S3_BUCKET']
s3.put(options)
test_params = {
object_key: object_key,
customer_key: Base64.encode64(customer_key),
md5_key: Base64.encode64(customer_key_md5),
}
Test.create(test_params)
end

但是我在检索对象并生成签名的 url 链接供用户下载时遇到了一些问题。
def retrieve_object(customer_key, md5)
options = {}
options[:key] = 'hello
options[:sse_customer_algorithm] = 'AES256'
options[:sse_customer_key] = Base64.decode64(customer_key)
options[:sse_customer_key_md5] = Base64.decode64(md5)
options[:bucket] = ENV['S3_BUCKET']
s3.get(options)
url = s3.presigned_url(:get)
end

该链接已生成,但当我点击它时,它会将我定向到一个亚马逊页面。
<Error>
<Code>InvalidRequest</Code>
<Message>
The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object.
</Message>
<RequestId>93684EEBA062B1C2</RequestId>
<HostId>
OCnn5EG7ydfoKzsmEDMbqK5kOhLFpNXxVRdekfhOfnBc6s+jtPYFsKi8IZsEPcd9ConbYUHgwC8=
</HostId>
</Error>

错误消息没有帮助,因为我不确定需要添加哪些参数。我想我可能缺少一些权限参数。

获取方法
http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#get-instance_method

Presigned_Url 方法
http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method

最佳答案

当您生成一个预签名的 GET 对象 URL 时,您需要提供所有将传递给 Aws::S3::Object#get 的相同参数。 .

s3.get(sse_customer_algorithm: 'AES256', sse_customer_key: customer_key).body.read

这意味着您需要将相同的 sse_customer_* 选项传递给 #presigned_url :
url = obj.presigned_url(:get,
sse_customer_algorithm: 'AES256',
sse_customer_key: customer_key)

这将确保开发工具包在您发出最终 GET 请求时正确签署 Amazon S3 期望的 header 。下一个问题是您现在负责将这些值与 GET 请求一起作为 header 发送。 Amazon S3 不接受查询字符串中的算法和 key 。
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri, {
"x-amz-server-side-encryption-customer-algorithm" => 'AES256',
"x-amz-server-side-encryption-customer-key" => Base64.encode64(cpk),
"x-amz-server-side-encryption-customer-key-MD5" => Base64.encode64(OpenSSL::Digest::MD5.digest(cpk))
})

请注意 - 在测试时,我发现了当前 v2.0.33 版本 aws-sdk 的预签名 URL 实现中的一个错误。 gem 。 This has been fixed now并且一旦发布就应该成为 v2.0.34 的一部分。

有关修补错误并演示的完整示例,请参阅以下 gitst:
  • 使用 cpk 上传对象
  • 使用 SDK 获取对象
  • 生成预先签名的 GET url
  • 仅使用 Net::HTTP 和预签名 URL 下载对象

  • 您可以在此处查看示例脚本:

    https://gist.github.com/trevorrowe/49bfb9d59f83ad450a9e

    只需更换 bucket_nameobject_key脚本顶部的变量。

    关于ruby-on-rails - 尝试生成预先签名的 url 链接,以便用户可以下载 Amazon S3 对象,但收到无效请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29291967/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com