Posted at

AWS S3のファイルを署名付きURLでアクセスする

EC2からS3にアクセスしてオブジェクトを返却してbase64でエンコードして・・なんて

実装も手間だし(多少処理時間も短縮したいし)なので、

private設定のままクライアント側から直接S3を参照できないものかと実験しました


環境


  • php 7.2

  • laravel 5.5

  • Vagrant 2.0.2

  • VirtualBox 5.2.6


準備

AWSコンソールのIAMでS3の権限をもつユーザを作成(readだけで良いはず)

S3はprivateにしておく(デフォルト)


手順

aws-sdk-phpを使います

◆SDKインストール


コンソール

php composer.phar require aws/aws-sdk-php


◆Controller

※認証情報は仮で直書きですが.envかconfigにもちましょう!


Controller

//認証情報

$s3 = new Aws\S3\S3Client([
'credentials' => [
'key' => 'XXXXXXXXXXX', //アクセスキー
'secret' => 'SSSSSSSSSSSSSSSSSSSSSSSSS', //シークレットキー
],
'version' => 'latest',
'region' => 'us-east-1' //リージョン
]);

$command = $s3->getCommand('GetObject', array(
'Bucket' => 'bucketName', //bucket
'Key' => 'work/test.png', //bucket名以下のファイルパス
));

$request = $s3->createPresignedRequest($command, '+1 minutes'); //有効期限 ※左記は1分で設定

//URL取得
$request->getUri();


こんな感じのURLが返却されます


URL

https://s3.amazonaws.com/bucketName/work/test.png?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXXXXXXXX%2F20190110%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190110T002959Z&X-Amz-SignedHeaders=host&X-Amz-Expires=60&X-Amz-Signature=3eb4e9937a3bcb42bc48b57694545484842a2645356949b438737aa965d2


これをviewに渡してあげて、imgタグに埋め込むと表示できます!

有効期限1分だけアクセスできるので、ロード後(厳密には1分後)には無効なURLになります!

まだまだ勉強中なので、もし間違っていたらご指摘いただけますと幸いです。(´;ω;`)