背景
Laravelを使用してS3への画像等のファイルをアップロードやダウンロードをしたいというケースが多いと思います。
今回はS3のPrivate Bucketのファイルに対して署名付きURLを発行する方法をご紹介します。
署名付きURL
個人情報が含まれるファイルをS3で管理する場合、基本的にはPrivate Bucketで管理し外部からのアクセスは禁止します。
署名付きURLとはBucket内のオブジェクトに対して有効期限内に一時的にアクセスできるURLを発行する機能です。
特定のユーザーに紐づく個人情報ファイルを一時的に配布するケースなどで使用出来ます。
Authorization HTTP ヘッダーを使用する代わりに、必要な情報をクエリ文字列パラメーターとして渡すことで、特定の種類のリクエストを認証できます。これは、サードパーティーのブラウザで、リクエストのプロキシを行わずにプライベートの Amazon S3 データに直接アクセスさせる場合に便利です。これを行うには、「署名付き」のリクエストを作成し、エンドユーザーのブラウザが取得できる URL としてエンコードします。さらに、署名付きのリクエストは、有効期限を指定することで制限できます。
実装
LaravelからAWSのリソースへは基本的にAccessKeyとSecretAccessKeyを使用すればアクセス可能です。
ただし上記の情報を.envなどに書き込み運用することはセキュリティ的にアンチパターンなので、EC2へIAMロールを割り当てます。
EC2へIAMロールを割り当てる記事は沢山あるので今回割愛します。
ライブラリはAWS SDK for PHPを使用します。
環境
- PHP 8.0.10
- Laravel 8
設定ファイル(.env)
#s3
FILESYSTEM_DRIVER=s3
AWS_S3_DEFAULT_REGION=ap-northeast-1
AWS_S3_ENDPOINT=http://s3.amazonaws.com/
# public
AWS_S3_ACCESS_KEY_ID_PUBLIC=
AWS_S3_SECRET_ACCESS_KEY_PUBLIC=
AWS_S3_BUCKET_PUBLIC=public-storage
AWS_S3_URL_PUBLIC=https://public-storage.s3.amazonaws.com/
AWS_S3_USE_PATH_STYLE_ENDPOINT_PUBLIC=false
# private
AWS_S3_ACCESS_KEY_ID_PRIVATE=
AWS_S3_SECRET_ACCESS_KEY_PRIVATE=
AWS_S3_BUCKET_PRIVATE=private-storage
AWS_S3_URL_PRIVATE=https://private-storage.s3.amazonaws.com/
AWS_S3_USE_PATH_STYLE_ENDPOINT_PRIVATE=false
S3 署名付き URL 生成メソッドの実装
use Aws\Credentials\CredentialProvider;
use Aws\S3\S3Client;
/**
* Create presigned url
* @param string $targetPathS3
* @return string
*/
private function createPresignedUrl(string $targetPathS3): string
{
// S3 クライアントを設定し、必要な認証情報やリージョンなどを指定。
$s3Client = new S3Client([
'credentials' => CredentialProvider::defaultProvider(),
'version' => 'latest',
'region' => env('AWS_S3_DEFAULT_REGION'),
// 認証URLをSSL化するために必要
'use_path_style_endpoint' => env('AWS_S3_USE_PATH_STYLE_ENDPOINT_PRIVATE'),
]);
//指定されたバケットとキーに対する操作を定義。
$command = $s3Client->getCommand('GetObject', [
'Bucket' => env('AWS_S3_BUCKET_PRIVATE'),
// 対象ファイルのs3ファイルパスを指定。
'Key' => $targetPathS3,
]);
// 有効期限1時間の署名付きURLを生成
return strval($s3Client->createPresignedRequest($command, '+1 hour')->getUri());
}
参考文献
一緒に働く仲間を募集しています!
株式会社コネクター・ジャパンでは一緒に働いてくれる仲間を募集しています!
事業拡大に伴い、エンジニアさんを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/cnctor/about
▼代表メッセージ
https://cnctor.jp/10years-anniversary/
▼応募はこちら
https://www.wantedly.com/projects/1522201