Help us understand the problem. What is going on with this article?

S3に保存した画像を表示する(Rails)

概要

例えば、あるサービスで画像をアップロードする際にS3を使うことはよくあるだろう。
そのS3にアップロードした画像を表示させたいということは結構あるのでは?(私がそれをやりたい)
私がやりたいのは以下の条件である。

  • S3はパブリックアクセスをオフ
  • 通常S3にアクセスできるのは特定のプログラムからのみ

この条件で、サービスからのみ画像を表示するようにする方法を書きます。

実行環境

Ruby 2.6.3
AWS S3

手順

S3について

前述した通り、パブリックアクセスはオフにしておきます。

ポリシーはこれぐらいしか書いてません。

S3policy
{
    "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になります。

image.png

これを回避するために一時的に閲覧可能となる期限付きURLというものがあります。

期限付きURLについて

期限付きURLとは、文字通り一時的に閲覧可能となるURLで、指定した時間を経過すると閲覧できなくなるものです。
これを利用して、サービス利用者のみS3に保存された画像を閲覧できるようにします。

ここではRubyでのやり方を示しますが、他の言語でもAWSのSDKがあればできるはずです。

AWS S3 SDKのインストール

Gemfileを使った方法を書きますが、使わない方はgemでインストールしてください。
Gemfileに以下を書いてインストールします。

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を入れれば良いだけです。

以上 :slight_smile:

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away