##概要
例えば、あるサービスで画像をアップロードする際にS3を使うことはよくあるだろう。
そのS3にアップロードした画像を表示させたいということは結構あるのでは?(私がそれをやりたい)
私がやりたいのは以下の条件である。
- S3はパブリックアクセスをオフ
- 通常S3にアクセスできるのは特定のプログラムからのみ
この条件で、サービスからのみ画像を表示するようにする方法を書きます。
##実行環境
Ruby 2.6.3
AWS S3
##手順
S3について
前述した通り、パブリックアクセスはオフにしておきます。
ポリシーはこれぐらいしか書いてません。
{
"Version": "2012-10-17",
"Id": "Policyxxxxxxxxxxx",
"Statement": [
{
"Sid": "Stmtxxxxxxxxxxx",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxx:user/your_name"
},
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::your_bucket_name/*"
}
]
}
S3の特定のオブジェクトにアクセスしようとすると以下の画面のようにAccessDeniedになります。
これを回避するために一時的に閲覧可能となる期限付きURLというものがあります。
期限付きURLについて
期限付きURLとは、文字通り一時的に閲覧可能となるURLで、指定した時間を経過すると閲覧できなくなるものです。
これを利用して、サービス利用者のみS3に保存された画像を閲覧できるようにします。
ここではRubyでのやり方を示しますが、他の言語でもAWSのSDKがあればできるはずです。
AWS S3 SDKのインストール
Gemfileを使った方法を書きますが、使わない方はgemでインストールしてください。
Gemfileに以下を書いてインストールします。
gem 'aws-sdk-s3'
期限付きURLの発行
以下の例ではプログラムからのみアクセスできるようにS3を設定しているのでCredentialを指定しています。
表示時間は60秒として設定しました。
s3 = Aws::S3::Resource.new(
region: REGION_NAME, # 1. 利用しているリージョン
credentials: Aws::Credentials.new(
AWS_ACCESS_KEY, # 2. プログラムからアクセスできるユーザのアクセスキー
AWS_SECRET_ACCESS_KEY # 3. プログラムからアクセスできるユーザのシークレットキー
)
)
signer = Aws::S3::Presigner.new(client: s3.client)
presigned_url = signer.presigned_url(:get_object,
bucket: bucket_name, key: key, expires_in: 60)
Presigner.presigned_urlで期限付きURLを発行しています。
生成されたURLにアクセスすると閲覧できるはずです。
HTMLで画面に表示する場合には通常通りimgタグのsrcにこの期限付きURLを入れれば良いだけです。
以上