第34回: ミドルウェア — リクエストの「通過ゲート」で横断処理を集約する

章: 第4章: Laravelフレームワーク

認証チェックやログ出力を、各コントローラに個別に書いていませんか?

同じ処理を複数のコントローラに書くと、修正漏れやロジックの不一致が起きやすくなります。ミドルウェアを使えば、HTTPリクエストの前後に共通処理を1箇所で定義し、ルートに適用できます。

ミドルウェアなしで横断処理を書くと何が起きるか

各コントローラのアクションに if (!auth()->check()) abort(401); を書いていると、1箇所の修正が漏れるだけでセキュリティホールになります。ミドルウェアに集約することで、適用範囲を宣言的に管理できます。

ミドルウェアの良い例・悪い例

観点 悪い例 良い例
認証チェック 各アクション冒頭に個別記述 auth ミドルウェアをルートグループに適用
ロール確認 コントローラ内で if ($user->role !== 'admin') カスタムミドルウェア role:admin で宣言的に制御
ログ出力 各アクションにログ記述 ミドルウェアでリクエスト/レスポンスをまとめて記録
適用範囲 ルートに逐一 ->middleware('auth') group() でまとめて適用

チェックポイント: ミドルウェアの handle() メソッドは $next($request) の前後どちらに処理を書くかで動作が変わります。認証・認可は必ず $next の前に置き、レスポンス加工(例:ヘッダー付与)は後に置きましょう。

コードサンプル


<?php
// php artisan make:middleware CheckRole
class CheckRole {
    public function handle(Request $request, Closure $next, string $role): Response {
        if ($request->user()?->role !== $role) {
            abort(403, 'アクセス権限がありません');
        }
        return $next($request);
    }
}
// ルートに適用
Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
});

まとめ & 次のステップ

  • ミドルウェアは横断的な関心事(認証・ログ・レート制限)を1箇所に集約できます
  • $next($request) の前後で処理タイミングを制御できます
  • group() を使って適用範囲を宣言的にまとめましょう
  • カスタムミドルウェアは app/Http/Middleware/ に作成し、bootstrap/app.php に登録します
  • テストでは withoutMiddleware() を使って特定ミドルウェアをスキップできます

次回は Laravelの認証(Breeze) を学びます。認証機能を最小構成で素早く導入するスターターキットの使い方を整理しましょう。

Related Articles