あいつ、Controllerの前でなにかやってるんだけど、
初見だと「なんかよくわからんやつ」くらいの印象しか持てません。
ただ、ルーティングが増えてきたり、認証や制限が必要になってくると、
Middlewareって仕組みをちゃんと知ってるかどうかで、コードの見通しがだいぶ変わってくるので理解しておきたいよくわからんやつになります。
この記事では、Middlewareって何をやってるのか?どこで設定されてるのか?
それから、自分で書くときに何に気をつけたらいいのか、みたいなところを整理してみたいと思います。
- 1. Middlewareってなにしてるの?
- 1.1. $next($request)ってなに?
- 2. Middlewareってどこで管理されてるの?
- 2.1. 💡 ざっくり3パターンある
- 2.2. 例:ルートに個別でミドルウェア指定する
- 3. 自分でMiddleware書くと、何がラクになるの?
- 3.1. 【再】ルートに直接指定する
- 3.2. Controllerごとに適用
- 4. Middleware失敗あるある〜🎉
- 4.1. エラーメッセージが優しい?
- 4.1.1. 優しさ?その1:$next($request) を returnしなくても肯定してくれるから地獄💀
- 4.1.2. 優しさ?その2:routeMiddleware に登録してないMiddlewareをルートで呼ぶ
- 4.2. ❌ $next($request) の後に処理を書くのを忘れる
- 4.3. ❌ Middlewareの順番を気にしない
- 5. Middlewareってどんなときに使うといい?
- 5.1. Middleware向きの処理
- 5.2. 🛠 具体的な判断ポイント
- 5.3. 💡 Laravelくん的な推奨設計(実装のポイント)
Middlewareってなにしてるの?
Laravelでリクエストを受け取るとき、Controllerに直で届くわけじゃなくて、
「Middleware」という通り道を経由してから入ってくる仕組みになってます。
ここでは、ログインチェックをしたり、特定のIPを弾いたり、
メンテナンス中の表示をしたり、「とりあえず中に入る前に一つやらして」みたいなことをまとめてやる。
public function handle(Request $request, Closure $next)
{
if ($request->ip() === '127.0.0.1') {
return response('ローカルアクセスは禁止です', 403);
}
return $next($request);
}
このMiddlewareは、リクエストが127.0.0.1(ローカル)から来てたら、そこで弾く。
そうじゃなければ、$next($request)
で「次の処理(たとえばController)」にバトンを渡す。
$next($request)
ってなに?
これは「次のMiddlewareかControllerにリクエストを渡す」って意味。
Laravelは複数のMiddlewareを順番に通していくんで、
それぞれが $next($request)
を実行することで、次へと処理が流れていく。
つまり、Middlewareはリクエスト処理のリレー走みたいなもの。
バトンを渡さないと、後ろのやつが動かない。

$next
って型見たら Closure
になっててびっくりするよね〜。
Middlewareってどこで管理されてるの?
Middlewareって、Controllerの前にあるフィルターですよ、って話を前章でしましたが、
じゃあ「そのフィルター、どこにあるの?」って話をそろそろしないと気持ち悪い。
LaravelはMiddlewareの登録と実行を、ほぼapp/Http/Kernel.php
で管理してます。
このファイル、基本はあんまり触らないけど、裏ではめちゃくちゃ大事なことしてる。
class Kernel extends HttpKernel
{
protected $middleware = [
// グローバルに適用されるMiddleware
];
protected $middlewareGroups = [
'web' => [
// セッション、CSRF、Cookie系など
],
'api' => [
// API用の制限とか
],
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
// ここで個別に呼べるやつ
];
}
この構造が、Middlewareの三層構造みたいなもの。
💡 ざっくり3パターンある
種類 | どこで使う? | いつ動く? |
---|---|---|
middleware | 全リクエストに自動で適用 | 常に |
middlewareGroups | ルートグループ(web, api)ごとに使う | web.php / api.php で分かれる |
routeMiddleware | ルートやControllerに個別に指定 | 必要なときだけ |
例:ルートに個別でミドルウェア指定する
Route::middleware(['auth', 'verified'])->get('/dashboard', [DashboardController::class, 'index']);
このとき、routeMiddleware
に 'auth'
と 'verified'
が登録されてないと、
「ミドルウェアなんて知らんがな」って怒られる。
Controllerに直接指定するパターンもある:
class DashboardController extends Controller
{
public function __construct()
{
$this->middleware(['auth']);
}
}

Kernel.phpってLaravelくんの指令書みたいなものって考えると親しみでてくるね〜。
自分でMiddleware書くと、何がラクになるの?
Laravelを触ってると、認可チェックや条件分岐をなんとなくControllerの中に書いてること、ありませんか?
たとえばこういうやつっす:
public function index()
{
if (!auth()->user()?->isAdmin()) {
return redirect('/');
}
// 管理者向けの処理
}
いや、普通ですけど?って思いますよね。
ただ、もしこれをやっているあなたに朗報です。もっとControllerが単純になります🤩
事前チェックをまとめて外に出せるので、Controllerがやるべきことに集中できるようになるんですよ。
public function index()
{
// もう「管理者であること」は保証されてる状態
return view('admin.dashboard');
}
もちろんこれをやるためには1章で例に出したようにMiddlewareを指定する必要があります。
指定方法色々あるので、再掲がてら、色々やり方を紹介しましょう。
【再】ルートに直接指定する
Route::middleware(['auth', 'verified'])->get('/dashboard', [DashboardController::class, 'index']);
こういう利用法方法が一般的なんじゃないでしょうか。
ちなみにGroupに対しても適用可能です。
Route::middleware('web')->group(function () {
Route::get('/home', [HomeController::class, 'index']);
Route::get('/settings', [SettingsController::class, 'edit']);
});
ちまちまやらないでよくて便利っすね。ちなみにネストも可能。
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::middleware('admin')->group(function () {
Route::get('/admin/users', [AdminUserController::class, 'index']);
Route::get('/admin/settings', [AdminSettingController::class, 'index']);
});
});
ネストすることで表現力が広がりますな。
Controllerごとに適用
class DashboardController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('verified')->only('index');
}
}
念の為補足しておくと、middlewareはサービスコンテナん中に入ってるんで、$this->middleware
みたいな波動拳飛び道具使えるんですね。
ぶっちゃけこの指定するくらいだったらRouteに書いた方が賢そうに見えます。

Controllerに書くのってなんか潜在バグ産みそうで怖いかも〜。あれ、どこにMiddreware書いたっけ〜って後でならないような仕組みづくりを考えた方がいいかもね〜。
Middleware失敗あるある〜🎉
ここまでMiddlewareの使い方を見てきました。
ここからはおまけで、LaravelのMiddleware実装でやりがちな失敗例を挙げていきます。
Laravelはエラーメッセージが優しすぎて、
“根本の設計のミス”を黙って受け入れてしまう場合があります、Middlewareの使い方も注意が必要。
エラーメッセージが優しい?
優しさ?その1:$next($request)
を returnしなくても肯定してくれるから地獄💀
public function handle(Request $request, Closure $next)
{
$next($request);
// return 忘れた
}
Laravel:「いいよ、いいよ!return つけ忘れちゃうことあるもんね☺️」
実際にはレスポンス返らず、ここで処理終了(Controllerが動かない)。「明確なエラー」としてLaravelは怒らない。
優しさ?その2:routeMiddleware に登録してないMiddlewareをルートで呼ぶ
Route::middleware(['hogehoge'])->get('/dashboard', ...);
Laravel:「あー、hogehogeってMiddlewareは無いんだよね〜。でもそれ作ってないっていうのもユーザーさんに悪いしなー。」
Class not found って言われるけど、“Middleware名のミスだよ”って教えてはくれない。
上記を踏まえた上であるあるいきます。
❌ $next($request)
の後に処理を書くのを忘れる
public function handle(Request $request, Closure $next)
{
$next($request);
// この処理、実行されません
Log::info('after request');
}
returnを忘れると、値が消える。
“実行はされるけどレスポンス返さないやつ”になって、⚪︎ぬ💀
❌ Middlewareの順番を気にしない
protected $middlewareGroups = [
'api' => [
\App\Http\Middleware\CheckRateLimit::class,
\App\Http\Middleware\Authenticate::class,
],
];
順番が逆だと、「認証前にレート制限」とかいう意味不明な処理順になることがある。
Middlewareって“上から順に通る”だけなんで、意図しない構成にすると挙動バグる。

Laravelくん優しすぎて、だいたい黙って通してくれるんだよね〜。
Middlewareってどんなときに使うといい?
ここまでMiddlewareの仕組みや使い方を見てきましたが、
最後にMiddlewareの使いどきでも置いといて終わろうと思います。
Middleware向きの処理
処理内容 | 使いどころ |
---|---|
認証チェック | auth ミドルウェアでログイン済みかを確認 |
ロールチェック | 管理者だけ通したいエリアなど |
IP制限 | 特定のIPだけ許可したいAPIなど |
メンテナンス表示 | アプリ全体または一部にメンテナンス表示を入れる |
リクエストログ出力 | どのルートにどんなアクセスが来てるかログに残す |
APIキー検証 | 外部連携の入口で認証処理を挟む |
CORS対応 | APIで必要なヘッダーの付け足しやオリジン制限 |
レート制限(throttle) | APIなどで同一IPからのアクセスを制限 |
🛠 具体的な判断ポイント
- ✅ 「この処理、複数のルートで必要なんだけど…」
→ Middlewareに出すと再利用しやすい - ✅ 「Controllerが条件分岐まみれになってきた…」
→ ロジックをMiddlewareに逃がして責務を分ける - ✅ 「ルートを見ただけで、何が必要かわかるようにしたい」
→ Middlewareで必要な条件を外から見えるようにする
💡 Laravelくん的な推奨設計(実装のポイント)
- Controllerに書くより、“通過条件”はMiddlewareで書いた方が整理しやすい
- Kernelで定義 → ルートに適用 → 実装は分離、って流れを覚えておけば、だいたい困らない
- Middlewareはコードの“入り口”の管理。フロントでいうところの「画面に来る前のバリデーション」みたいな感覚でOK
以上です。あざした。
コメントを残す