問題の発生
Laravel 10 で構築されたプロジェクトにおいて、未定義のルートにアクセスした際に 404 エラーページへ遷移する際、ログイン状態が正しく表示されない問題が発生。
具体的には、ログインしているにも関わらず、セッションが開始されていなかった。
結論
フォールバックルートで対応できました。
Route::fallback(function () {
abort(404);
});
原因の調査
この問題は、404 エラーが発生した際に、StartSession
ミドルウェアが実行されず、セッションが開始されないことが原因でした。
StartSession
ミドルウェアは、通常、web
ミドルウェアグループに含まれており、定義済みのルートにアクセスした際には実行される。
しかし、未定義のルートにアクセスした場合は、web
ミドルウェアグループが適用されないため、セッションが開始されない。
解決策の検討
1. 例外ハンドラでの対応
当初は、例外ハンドラ (app/Exceptions/Handler.php
) の render
メソッドをオーバーライドし、404 エラーが発生した際に StartSession
ミドルウェアを動的に適用することで対応しようとした。
ググるとこんな感じのStackOverflowの記事がいくつか出てくる。
public function render($request, Throwable $exception): Response
{
try {
// リクエストされたパスに対応するルートを取得
// ルートが存在しない場合は例外が発生
Route::getRoutes()->match($request);
} catch (\Exception) {
// ルートが存在しない場合は一時的にルーティングを設定してミドルウェアを適用
Route::any(request()->path(), function () use ($e, $request) {
return parent::render($request, $e);
})->middleware('web');
return app()->make(Kernel::class)->handle($request);
}
return parent::render($request, $e);
}
2. フォールバックルートでの対応
フォールバックルートを利用して、未定義のルートにアクセスした際にもwebミドルウェアを通過させる。
Route::fallback(function () {
abort(404);
});
今回の問題であれば最もフィジカルで、最もプリミティブで、そして最もフェティッシュ
な方法なのでこちらを採用。
まとめ
Laravel の 404 エラーページでログイン状態が正しく表示されない問題は、未定義のルートへのアクセス時にセッションが開始されないことが原因でした。
未定義のルートアクセス時に特別なミドルウェアを適用したい場合は1、それ以外は2で対応すれば良いと思います。
参考