S3 署名付き URL を使用してファイルをアップロードすると、パブリック読み取りアクセスが可能になります

概要

Ruby on Rails と AWS gem を使用しています。 アップロードおよびダウンロード用の署名付き URL を取得できます。 しかし、URLを取得するとファイルがないため、aclを「public-read」に設定します ダウンロード URL では機能しません。

使用例は次のとおりです。 1、サーバーは、認証情報がないと読み取れないコンテンツをバケットにアップロードするためのパスをユーザーに提供します。 2. そして、そのコンテンツは後で公開する必要があり、誰でも読めるようになります。

明確にするために: 私はファイルをアップロードしているのではなく、ユーザーがアップロードできる URL を提供しています。その際、一般の人が読み取れる URL もユーザーに提供したいと考えています。自分でファイルをアップロードしたほうが簡単なようです。また、読み取り URL は無期限である必要があります。

解決策

PUT オブジェクト リクエストの署名付き URL を生成する場合、アップローダーが使用する必要があるキーと ACL を指定できます。ユーザーに「files/hello.txt」キーを使用してオブジェクトをバケットにアップロードしてもらい、そのファイルを公開して読み取り可能にする必要がある場合は、次のようにすることができます。

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"

put_url を他の人に渡すことができます。この URL により、オブジェクトを URL に PUT できるようになります。それには次の条件があります。

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)

オブジェクトが他の人によってアップロードされたので、#public_url に対して通常の GET リクエストを行うことができます。これはブラウザ、curl、wget などで実行できます。