Laravel + Localstack + S3で署名付き URLを利用する

Laravel + Localstack + S3で署名付き URLを利用する

Twitter LINEで送る Facebook はてなブログ

概要

Laravelを用いて署名付き URLを利用する機会があり
ファイルをS3にアップロードして署名付き URLの発行を一連のサンプル化
blade側はFormと input='file' name='image' を想定してサンプル化しています。
自分の利用時には、ファイルをアップロードした情報とS3のパスと証明書付きURLはModelに組み込んでいます

事前準備

事前にdockerの準備こちらの記事を参照

Laravelの設定ファイル

config/filesystem.php

・・・
's3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
        'endpoint' => env('AWS_S3_ENDPOINT'),
        'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
        'throw' => false,
    ],
・・・     

.env

・・・
AWS_ACCESS_KEY_ID=dummy
AWS_SECRET_ACCESS_KEY=dummy
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=laravel
AWS_S3_ENDPOINT=http://localstack:4566
AWS_USE_PATH_STYLE_ENDPOINT=true
・・・

Http/Controllers/ImageController.php

<?php

namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Storage;
use Config;
use Aws\S3\S3Client;
use Aws\Exception\AwsException;


/**
 * 画像コントローラー
 */
class ImageController extends Controller
{
    
    /**
     * 画像を保存し署名付き URLを取得.
     */
    public function store(Request $request) {
        $validated = $request->validated();
        $s3path = Storage::disk('s3')->put('/', $request->file('image'));
        if ($s3path) {
            $s3Client = Storage::disk('s3')->getClient();
            $cmd = $s3Client->getCommand('GetObject', [
                'Bucket' => config('filesystems.disks.s3.bucket'),
                'Key' => $s3path
            ]);
            $presignedRequest = $s3Client->createPresignedRequest($cmd, '+27 hours');
            // docker環境用のためホストを強制的にローカル動作用に置き換え
            $url = str_replace("://localstack:" , "://localhost:", (string)$presignedRequest->getUri());
            return response()->json(['url' => $url]);
        }
        return response()->json(null);
    }
}

まとめ

LocalStack自体は便利で良いものです。
ローカル内で色々、検証ができる点を考えるとAWSがなくてもUTとかで来てコスト的にも良いので利用を拡大していきたいと思っています。
他にも使えそうなサービスを検証してみようと考えています。