対象バージョン: Laravel 13.x / PHP 8.3+(2026年時点のシリーズ基準)
一次ソース: Middleware / Routing / Release Notes
こんにちは。この記事では、Laravel 13.x で ミドルウェアを実装する基本 を、現行の公式ドキュメントに沿って整理します。作成(make:middleware)、handle での前後処理、bootstrap/app.php への登録、ルート割り当て、パラメータまでを通します。認証設計や API 全体の話は扱いません。まずは「自分で作ったミドルウェアを、正しい場所に登録してルートに掛けられる」状態を目指します。
この記事で分かること
- ミドルウェアの役割(HTTP リクエストの検査・フィルタ)
php artisan make:middlewareとhandleの書き方(before / after)- Laravel 13.x の登録場所(
bootstrap/app.phpのwithMiddleware) - ルートへの割り当てとパラメータ付きミドルウェア
- Laravel 10 時代の
Kernel.phpとのよくある落とし穴
対象バージョンと前提
本記事の前提は Laravel 13.x / PHP 8.3+ です。Laravel 13.x は PHP 8.3 以上を要求し、フレームワーク本体の composer.json も "php": "^8.3" です(Release Notes)。調査時点で確認した laravel/framework 13.x の最新 stable は v13.34.0(2026-09-29)です。
登録の正本は bootstrap/app.php の withMiddleware です。 laravel/laravel 13.x のスケルトンには app/Http/Kernel.php がなく、app/Http 配下は主に Controllers です。古い記事の Kernel.php 前提は、現行手順として使わないでください(差分は後半で短く触れます)。
ミドルウェアとは何か
ミドルウェアは、アプリケーションに入ってくる HTTP リクエストを検査・フィルタするための仕組み です。たとえばトークンの確認、ロケールの設定、レスポンスヘッダの付与など、「コントローラの手前(または直後)で毎回やりたいこと」を分離するのに向いています。
イメージとしては、リクエストがコントローラに届くまでのレイヤーです。通過させてよければ次へ渡し、ダメならここでレスポンスを返して止めます。ユーザー定義のミドルウェアは、通常 app/Http/Middleware に置きます。
ミドルウェアの作成(make:middleware)
新しいクラスは Artisan で生成します。
php artisan make:middleware EnsureTokenIsValid
app/Http/Middleware/EnsureTokenIsValid.php が作られます。中心は handle メソッドです。型ヒント例は公式どおり、戻り値を Response にします。
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureTokenIsValid
{
/**
* Handle an incoming request.
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->input('token') !== 'my-secret-token') {
return response('Invalid token.', 401);
}
return $next($request);
}
}
リクエストを先に進めるときは $next($request) を返します。止めるときは、ここでレスポンスを返して $next を呼びません。ミドルウェアはサービスコンテナ経由で解決されるため、コンストラクタでの依存注入も使えます。
リクエスト前後の処理
Before(コントローラの前)
$next($request) を呼ぶ 前 に処理を書くと、リクエストがアプリケーション本体に入る前に実行されます。上のトークン例がこれです。
After(コントローラの後)
先に $response = $next($request) で先を実行し、返ってきたレスポンスに手を加えてから返すと、後処理になります。
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Example', 'Middleware');
return $response;
}
登録方法(bootstrap/app.php)
Laravel 13.x では、ミドルウェアの登録・エイリアス・グループへの追加を bootstrap/app.php の withMiddleware で行います。スケルトンには空のコールバックが用意されています。
->withMiddleware(function (Middleware $middleware): void {
//
})
グローバル(すべての HTTP リクエスト)
すべてのリクエストで動かしたい場合は append / prepend します。
->withMiddleware(function (Middleware $middleware): void {
$middleware->append(\App\Http\Middleware\EnsureTokenIsValid::class);
// 先頭に入れたい場合
// $middleware->prepend(\App\Http\Middleware\EnsureTokenIsValid::class);
})
既定のグローバルスタックを自分で並べ替える場合は $middleware->use([...]) も使えます(必要なときだけ)。
エイリアス
短い名前でルートに掛けたいときは alias を登録します。
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'token.valid' => \App\Http\Middleware\EnsureTokenIsValid::class,
]);
})
組み込みでも、例えば auth / auth.basic / can / guest / signed / throttle / verified などが既定でエイリアスされています。
web / api グループ
Laravel にはあらかじめ web と api のミドルウェアグループがあります。routes/web.php と routes/api.php のルートには、それぞれ自動で適用されます。既定グループに自分のクラスを足す例です。
->withMiddleware(function (Middleware $middleware): void {
$middleware->web(append: [
\App\Http\Middleware\EnsureTokenIsValid::class,
]);
$middleware->api(prepend: [
\App\Http\Middleware\EnsureTokenIsValid::class,
]);
})
独自グループは appendToGroup / prependToGroup で定義し、ルートでは ->middleware('group-name') のように使います。
$middleware->appendToGroup('custom', [
\App\Http\Middleware\EnsureTokenIsValid::class,
]);
ルートへの割り当て
特定ルートだけに掛ける場合は、ルート定義で middleware を指定します。
use App\Http\Middleware\EnsureTokenIsValid;
Route::get('/profile', function () {
// ...
})->middleware(EnsureTokenIsValid::class);
Route::get('/dashboard', function () {
// ...
})->middleware([EnsureTokenIsValid::class, 'auth']);
エイリアス名でもクラス名でも構いません。複数は配列で並べます。
withoutMiddleware の注意
ルートからミドルウェアを外すときは withoutMiddleware([...]) を使います。ただし 外せるのはルートに割り当てたミドルウェアだけ で、グローバルスタックには効きません。
Route::get('/public', function () {
// ...
})->withoutMiddleware([EnsureTokenIsValid::class]);
ミドルウェアパラメータ
handle の $next のあとに追加引数を取れます。ルート側では、クラス名(またはエイリアス)の後ろに :値 を付けます。複数はカンマ区切りです。
public function handle(Request $request, Closure $next, string $role): Response
{
if (! $request->user() || ! $request->user()->hasRole($role)) {
abort(403);
}
return $next($request);
}
Route::put('/post/{id}', function (string $id) {
// ...
})->middleware(\App\Http\Middleware\EnsureUserHasRole::class.':editor');
(任意)優先順位と Terminable
ルートへの並び以外で実行順を細かく決めたいときは、bootstrap/app.php で $middleware->priority([...]) や prependToPriorityList / appendToPriorityList を使えます。入門では、まずルート配列の順序で足りることが多いです。
レスポンス送信後に後始末したい場合は、terminate(Request $request, Response $response): void を定義できます。Web サーバが FastCGI のとき、レスポンス送信後に自動で呼ばれます。詳細は公式の Terminable Middleware を参照してください。本記事では深掘りしません。
Laravel 10 とのよくある落とし穴
| Laravel 10.x 頃 | Laravel 11+ / 13.x |
|---|---|
app/Http/Kernel.php の $middleware / $middlewareAliases / $middlewareGroups |
bootstrap/app.php の withMiddleware |
| スケルトンに Kernel.php がある前提の解説が多い | 13.x スケルトンに Kernel.php は無い(URL も 404) |
古いチュートリアルを写すと「Kernel.php が見つからない」になりがちです。現行は bootstrap/app.php だけを主経路にしてください。
まとめ
- ミドルウェアは HTTP リクエストの検査・フィルタ用レイヤー
- 作成は
php artisan make:middleware、処理の中心はhandleと$next($request) - before は
$nextの前、after は$response = $next($request)の後 - Laravel 13.x の登録は
bootstrap/app.phpのwithMiddleware(グローバル / エイリアス / web・api) - ルートは
->middleware(...)。withoutMiddlewareはグローバルには効かない - パラメータは
Class::class.':param' Kernel.phpを現行の主教材にしない