Laravelでレスポンスヘッダに共通でcache-control: no-cache, no-storeを設定したい時

LIFFアプリに使うAPIをLaravelで開発していてキャッシュが問題になったので。

レスポンスヘッダにno-cache, no-storeを設定したかった。

middlewareで設定すればOK。

レスポンスヘッダを変えるmiddlewareの作成

まずは作成する。

php artisan make:middleware NoCacheResponse

 

middlewareの実装

実装。レスポンスなので$nextの戻り値をいじる。

# app\middleware\NoCacheResponse

class NoCacheResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        return $response->setCache(['no_store' => true, 'no_cache' => true]);
    }
}

setCacheメソッドを使います。

設定したい値をキーにして値をtrueにした配列を渡す。

注意点!

no_cacheとアンダバーにします。ハイフンでは正しく挙動しません。

この辺の謎を知りたい人はコードを直接確認してね。

メソッドの内部でアンスコをハイフンにstr_replaceしています。

https://github.com/symfony/symfony/blob/6.4/src/Symfony/Component/HttpFoundation/Response.php#L1006

middlewareをKernel.phpのmiddlewaregroupに追加

これをapp/Http/Kernel.phpに追加。

今回はapiなのでこちらに。


     /** The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\NoCacheResponse::class, #追加する部分
        ],
    ];

結果。

responseヘッダ

route側をいじる必要もなく、便利かなと。

もちろんエンドポイントによってはcacheさせる /させないをコントロールする場合にはルートごとに設定してくださいね。