PHP
AWS
S3
laravel

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になります!

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