章: 第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) を学びます。認証機能を最小構成で素早く導入するスターターキットの使い方を整理しましょう。