1. Laravelにおけるミドルウェアの位置づけ
-
HTTP リクエスト―レスポンスのライフサイクルを横断的にフックし、共通処理(認証・ログ・CORS など)を挿し込む仕組み
-
app/Http/Kernel.phpで グローバル/ルートグループ/単一ルートの 3 段階で登録・適用順を制御 -
PSR-15 とは異なり、スタック方式(前後段で
$next($request))で実装される
2. 認証ミドルウェア
| ミドルウェア | 目的 | 利用例 | 主な設定/拡張ポイント |
|---|---|---|---|
auth |
セッション/トークンいずれも対応。指定ガードで未認証ならリダイレクト | Route::middleware('auth')->group(...) |
config/auth.php でガード種別を定義 |
auth.basic |
HTTP Basic 認証を最小構成で提供 | Route::get('/admin', fn() => ...) ->middleware('auth.basic') |
AUTH_USER ヘッダで簡易保護。本番では TLS 必須 |
auth:sanctum |
API トークン(Cookie / Bearer)認証 | SPA⇔API を統合認証。Route::middleware('auth:sanctum')... |
EnsureFrontendRequestsAreStateful で SPA Cookie を許可 |
auth:api |
Laravel Passport / OAuth2 アクセストークン用 | 大規模 API でスコープ制御 | config/passport.php, php artisan passport:install |
| カスタム | 例)RoleMiddleware, AgeCheck |
Route::middleware(['auth', 'role:admin'])->... |
php artisan make:middleware RoleMiddleware で生成 |
実装のポイント
-
生成
php artisan make:middleware Authenticate(既定クラスは存在) -
ガード切替 ルート側で
auth:guard名を付与すると$this->auth->guard($name)->check()に自動反映 -
未認証時の戻り値 Web =リダイレクト、API =
401 JSONを使い分けるため、redirectTo()をオーバーライド -
複数ミドルウェア
Route::middleware(['auth','verified','throttle:60,1'])...のように 配列記法 で順番を保持 -
テスト
actingAs($user,'api')でガードを指定し、Feature Test で認証フローを検証
3. CORS 対応ミドルウェア
3-1. 基本構造
-
Laravel 7 以降は
HandleCorsを標準同梱(内部では fruitcake/laravel-cors コンポーネント) -
既定で
apiスタックに含まれ、SPA × API 構成で プリフライト OPTIONS を自動処理
3-2. 設定ファイル config/cors.php
config/cors.php| キー | 役割 | よく使う設定例 |
|---|---|---|
paths |
適用エンドポイント | ['api/*', 'sanctum/csrf-cookie'] |
allowed_origins |
許可ドメイン | ['https://example.com'] or ['*'] |
allowed_methods |
許可 HTTP メソッド | ['GET','POST','PUT','DELETE','OPTIONS'] |
allowed_headers |
クライアント送信を許可するヘッダ | ['Content-Type','Authorization','X-Requested-With'] |
supports_credentials |
Cookie 認証を許可するか | true(Sanctum の SPA モードで必須) |
max_age |
プリフライトのキャッシュ秒数 | 3600 |
Tip:
.envへCORS_ALLOWED_ORIGINSなどを置き、環境別に動的読み込みすると運用が楽になります。
3-3. カスタマイズ例
3-4. テストとデバッグ
-
順序依存:
HandleCorsは 最上段 あるいは 最下段 に置くと意図しないヘッダ上書きが防げる -
キャッシュ: ブラウザは
max_age内でリクエストを省くため、設定変更後はキャッシュを削除する
4. ベストプラクティスまとめ
| 項目 | 推奨策 |
|---|---|
| ガード設計 | Web と API でガードを分離し、auth vs auth:sanctum の衝突を避ける |
| リダイレクト先 | SPA で 401 JSON を返したい場合は Authenticate::$except ではなく redirectTo() を上書き |
| ミドルウェア順序 | CORS → ProxyTrust → RateLimit → 認証 の順が典型 |
| 環境変数化 | CORS 許可オリジン・トークンクッキー Domain は .env に持たせてデプロイ差分をなくす |
| テスト自動化 | Feature Test で「認証成功/失敗」「CORS ヘッダ」をアサートしてリグレッションを防止 |
| セキュリティ | allowed_origins をワイルドカード * にしない。公開 API のみ限定的に許可範囲を広げる |
| バージョンアップ | Laravel 11 以降は HandleCors がグローバル登録済み。果樹系パッケージは不要になったため、composer.json から削除しておく |
まとめ
-
認証ミドルウェアは ガード・トークン種別・リダイレクト挙動 を軸に設計・拡張する
-
CORS は
HandleCors+config/cors.phpで原則完結。SPA → API、モバイルアプリ → API 連携でもほぼ同じ構成で運用できる -
登録順序と環境ごとの設定切替 を押さえれば、セキュアかつメンテナブルなミドルウェア構成を構築できる
ChatGPT4o 生成日:2025/06/23