使用S3 Presigned-URL上传一个文件,该文件将具有公共读取权限

Cod*_*tix 8 ruby ruby-on-rails amazon-s3 amazon-web-services

我正在使用Ruby on Rails和AWS gem.我可以获得预先签名的URL以供上传和下载.但是当我得到URL时没有文件,因此在download-url上将acl设置为'public-read'不起作用.

用例是这样的:1,服务器为用户提供了一个将内容上传到我的存储桶的路径,如果没有凭据,则无法读取.2,该内容需要在以后公开:任何人都可以阅读.

澄清一下:我没有上传文件,我提供的URL供我的用户上传.那时,我还想给用户一个公众可读的URL.如果我自己上传文件似乎会更容易.此外,读取URL需要永不过期.

Tre*_*owe 16

为PUT对象请求生成预签名URL时,可以指定上载者必须使用的密钥和ACL.如果我希望用户使用密钥"files/hello.txt"将objet上传到我的存储桶,并且该文件应该是公共可读的,我可以执行以下操作:

s3 = Aws::S3::Resource.new
obj = s3.bucket('bucket-name').object('files/hello.text')

put_url = obj.presigned_url(:put, acl: 'public-read', expires_in: 3600 * 24)
#=> "https://bucket-name.s3.amazonaws.com/files/hello.text?X-Amz-..."

obj.public_url
#=> "https://bucket-name.s3.amazonaws.com/files/hello.text"
Run Code Online (Sandbox Code Playgroud)

我可以把它put_url给别人.此URL将允许他们将对象PUT到URL.它具有以下条件:

  • PUT请求必须在给定的到期时间内完成.在上面的例子中,我指定了24小时.该:expires_in选项不得超过1周.
  • PUT请求必须指定'x-amz-acl'的HTTP标头,其值为'public-read'.

使用put_url,我可以使用Ruby的Net :: HTTP上传任何对象:

require 'net/http'

uri = URI.parse(put_url)

request = Net::HTTP::Put.new(uri.request_uri, 'x-amz-acl' => 'public-read')
request.body = 'Hello World!'

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true   
resp = http.request(request)
Run Code Online (Sandbox Code Playgroud)

现在该对象已被其他人上传,我可以向其发送一个vanilla GET请求#public_url.这可以通过浏览器,curl,wget等来完成.