AWS SDK for Ruby バージョン 2 で期限付きURLの発行

はじめに

前回、「AWS SDK for Ruby バージョン 2 を使用したS3バケットへのオブジェクトアップロード」でS3へオブジェクトのアップロードを行いました。 でも、このままではアップロードしただけで、誰もアップしたオブジェクトにアクセスができないですね。。。 ということで、今回はアップロードしたファイルをブラウザからアクセスできるように期限付きURLの発行をしてみたいと思います。 ちなみに期限付きURLとはその名の通り、URLを発行してから10分だったり3日だったり1週間だったりと、利用できる期限を持たせたURLです。


# 1. アクセス先の準備 前回、[「AWS SDK for Ruby バージョン 2 を使用したS3バケットへのオブジェクトアップロード」](http://blog.proudit.jp/2016/08/23/to-upload-a-file-using-the-aws-sdk-for-ruby.html#1.-ファイルアップロード先の準備)で作成したバケットを利用するので今回は省略します。
# 2. アクセスユーザーの用意 まずは、バケットへアクセスできるユーザーを準備しますが、[前回作成](http://blog.proudit.jp/2016/08/23/to-upload-a-file-using-the-aws-sdk-for-ruby.html#2.-アップロードユーザーの用意)した*kohei-no-iam*を利用したいと思います。

まずは「アクセス許可」→「ポリシーのアタッチ」をクリックします。

4-iam01.png

今回は AmazonS3ReadOnlyAccess をアタッチするだけでOKです。

4-iam02.png

4-iam03.png

以上でユーザーの用意は完了です。


# 3. スクリプトの作成 それではスクリプトを作成します。
$ vim presigned_url.rb

ファイルを開いたら以下の内容をコピペします。 また、その際にbucketnameobjectnameuploadfileアクセスキーIDシークレットアクセスキーは適宜変更してください。 バケットのリージョンをTokyoにしなかった場合も適切なリージョンに変更する必要があります。

# !/usr/bin/env ruby

require 'aws-sdk'

bucketname = "kohei-no-bucket"    # バケット名
objectname = "ceresso.png"        # オブジェクト名

Aws.config[:credentials] = Aws::Credentials.new(
  '********************',                      # アクセスキーID
  '****************************************',  # シークレットアクセスキー
)
s3 = Aws::S3::Resource.new(region:'ap-northeast-1')  # Tokyoリージョン
obj = s3.bucket(bucketname).object(objectname)
puts obj.presigned_url(:get, expires_in:60)   # expires_in:有効期限(秒)

実行権限を追加しておきます。

$ chmod +x presigned_url.rb

以上で準備完了です。


# 4. 実践! その前に、一応現在のバケットの設定が**「ウェブサイトのホスティングを有効にしない」**となっているのを確認しておきます。

5-test01.png

それでは実行です。

$ ./presigned_url.rb
https://kohei-no-bucket.s3-ap-northeast-1.amazonaws.com/ceresso.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=********************%2F20160824%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20160824T061832Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host&X-Amz-Signature=26eddaaad67a9f0e5d011b110ee34e271557c5f9f8bac82c9da655d58956245e

発行されたURLにアクセスしてみます。

5-test02.png

画像が表示されました。 それでは60秒過ぎてからもう一度アクセスしてみます。

5-test03.png

アクセスができなくなっているのが確認できました。 以上で期限付きURLの発行の完了です。


# おわりに 「期限付きURL」が発行できることによって、一時的なファイル共有が可能になるのでこれはとても便利なんじゃないかなと個人的には思います。 ただ、[ドキュメント](http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method)によるとこの期限付きURLは「1週間」を超える設定にはできないことです。

Raises: (ArgumentError) — Raised if :expires_in exceeds one week (604800 seconds).


# おまけ そこについても試してみました。

●ちょうど1週間(604800秒)の場合

$ ./presigned_url.rb 
https://kohei-no-bucket.s3-ap-northeast-1.amazonaws.com/ceresso.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=********************%2F20160825%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20160825T021333Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=709a0de7cf14bd002a9b7953da5e5c9433104ccf9743bb7fda0332bd17830043

●1週間+1秒(604801秒)の場合

$ ./presigned_url.rb 
/Library/Ruby/Gems/2.0.0/gems/aws-sdk-core-2.5.4/lib/aws-sdk-core/s3/presigner.rb:68:in `expires_in': expires_in value of 604801 exceeds one-week maximum (ArgumentError)
	from /Library/Ruby/Gems/2.0.0/gems/aws-sdk-core-2.5.4/lib/aws-sdk-core/s3/presigner.rb:50:in `presigned_url'
	from /Library/Ruby/Gems/2.0.0/gems/aws-sdk-resources-2.5.4/lib/aws-sdk-resources/services/s3/object.rb:189:in `presigned_url'
	from ./presigned_url.rb:14:in `<main>'

期限付きURLも期限付きだったんですねw

参考:AWS SDK for Ruby - presigned_url