S3 見習い兼 PHP と Ruby 初心者のかっぱ(@inokara)です。
既にご存知の方もいらっしゃると思いますが、Amazon S3 の各バケットに保存されているコンテンツ(オブジェクト)に期限をつけてアクセスさせることが出来る機能(以下、「期限付き URL 生成機能」)があります。これは一時的に一部の方にだけファイルをダウンロードさせたい時等に非常に便利な機能だと思います。
この期限付きの URL 生成方法について AWS SDK for PHP と AWS SDK for Ruby の二種類を利用した手順を簡単にまとめてみたいと思います。
尚、上記のドキュメントでは Pre-Signed URL(事前署名付き URL)とありますが、本記事はタイトルを除いて、全編を通して期限付き URL と呼びたいと思います。
いきなり制限で恐縮ですが、この期限付き URL 生成機能は SDK でのみ利用可能です。尚、今回利用する AWS SDK for PHP と AWS SDK for Ruby のドキュメントは下記の通りです。
必要に応じて見ましょう。
まずは AWS SDK for PHP を使って期限付き URL 生成機能を使ってみたいと思います。
こちら を参考にして Composer というツールを利用して AWS SDK for PHP をインストールします。尚、インストールした環境は下記の通りです。
まずは適当なディレクトリを作成しましょう。
mkdir -p ~/aws/
次に composer.json という Composer が利用するプロジェクトファイルを生成します。
cat << composer.json > EOT
{
"require": {
"aws/aws-sdk-php": "2.*"
}
}
EOT
次に Composer のインストールを行います。
curl -sS https://getcomposer.org/installer | php
この時点で Composer のインストールが終了です。Composer のインストールが終わったら AWS SDK for PHP のインストールです。
php composer.phar install
正常にインストールが終了した場合には以下のようなディレクトリ構成となっている(はず)です。
. ├── composer.json ├── composer.lock ├── composer.phar └── vendor 1 directory, 4 filesction_requests
上記のようになっていない場合には改めて手順や composer.json の中身等に間違いがないか確認しましょう。また、Composer を使わない AWS SDK for PHP のインストールについては以下のおまけをご確認ください。尚、インストールされる SDK のバージョンは 2.6.7 となります。これは composer.lock というファイルにて確認することが可能です。
"packages": [
{
"name": "aws/aws-sdk-php",
"version": "2.6.7",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
バケットを作って適当なファイルを置きましょう。既に対象のオブジェクトがある場合にはこのステップはすっ飛ばしましょう。
こちらのロゴ画像を利用させて頂きアップロードしました。
この時点で既にエンドポイント(リンク)が生成されているのが判りますが、このリンクにアクセスしても...
アクセス出来ませんね。
では、先ほどアップロードしたファイルにアクセス出来るように期限付きの URL を生成してみましょう。
先ほど SDK をインストールしたディレクトリと同じディレクトリに test.php というファイルを作成し、こちらを参考にして以下のようなコードを書きました。
<?php
require_once("./vendor/autoload.php");
$config = array(
'key' => 'AKxxxxxxxxxxxxxxxxxxxxxxxxx',
'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
);
use Aws\S3\S3Client;
$s3 = S3Client::factory($config);
$url = $s3->getObjectUrl("kappa-test", "fluentd.png", "1 minutes");
print $url;
見て判る通り...
次に getObjectUrl の引数に...
この test.php を以下のように実行します。
php test.php
実行すると...
上記のように長ったらしい URL が表示されますのでこの URL をコピーしてブラウザでアクセスしてみます。
おお、画像が表示されました。しばらくリロードを繰り返し続けると...
期限切れとなりアクセスが出来なくなりました。
<Expires>2014-06-19T05:42:34Z</Expires>
上記のように期限が切られていたことが判ります。
環境は以下のような環境でインストールします。
既に Ruby がインストールされていれば gem 一発です。
gem install aws-sdk --no-ri --no-rdoc -V
簡単ですね。
こちらを参考にして以下のようなコードを書いてみました。
#!/usr/bin/env ruby require 'aws-sdk' AWS.config( :access_key_id => 'AKxxxxxxxxxxxxxxxxxxx', :secret_access_key => 'xxxxxxxxxxxxxxxxxxxxxxx', ) obj = AWS::S3.new.buckets['kappa-test'].objects['fluentd.png'] print obj.url_for(:read, :expires => 5*60)
アクセスキーやシークレットアクセスキーが必要になるのは PHP 版と同様です。処理の流れとしては…
このコードを test.rb というファイル名で作成して実行権限を与えてから以下のように実行します。
./test.rb
以下のように URL が生成されます。
生成された URL をブラウザで確認してみましょう。
ロゴが表示されました。しばらくリロード繰り返しているうちに…
アクセス出来なくなりました。
ちなみに Expires を修正すればなんとかなるんぢゃないかなと思った方、ご安心(お諦め)ください。Expires を巻き戻しても問題なくアクセス制限が掛かった状態でした。
yum -y install php-amazon-sdk2
上記の場合には、バージョン 2.6.6 がインストールされます。また、
yum -y install php-amazon-sdk
の場合には、バージョン 1.6.2 がインストールされます。
記事をアップした後に記事を読んで下さった方から…
大容量なデータで期限内にダウンロードできなかった場合でもセッションが生きていたら大丈夫なんですか?
という鋭い質問を頂きましたので試してみました。
以下のような手順で実験を行いました。
結構デカイですね。
以下のようにスクリプトを修正してダウンロード期限を 60 秒間に設定します。
obj = AWS::S3.new.buckets['kappa-test'].objects['CentOS-6.5-x86_64-minimal.iso'] print obj.url_for(:read, :expires => 1*60)
スクリプトは AWS SDK for Ruby を利用します。
./test.rb
を実行して URL を発行します。
以下のようなダウンロードをあらかじめ用意しておいて…
#!/usr/bin/env bash cd ~/tmp/ echo "start : `date`" echo "" curl --limit-rate 10K -k -o test.iso "$1" echo "" echo "end : `date`"
以下のように実行すると…
download.sh https://kappa-test.s3.amazonaws.com/CentOS-6.5-x86_64-minimal.iso?AWSAccessKeyId=AKxxxxxxxxxxxxxxxxxxxxxxxx&Expires=1403227984&Signature=tgND5F1dc9NGQDMRWS3Y3Gk%2B5iM%3D
ダウンロードが開始されます…。
ブラウザから同じ URL を叩くと…
それれでも最初にダウンロードを開始したセッションは…
元記事はこちら