Laravel 11.x では、ミドルウェアの登録が従来の app/Http/Kernel.php
ではなく、bootstrap/app.php
に記述されるようになりました。
また、サービスプロバイダも artisan make:provider
コマンドで生成すると、自動的に bootstrap/providers.php
に登録されるようになっています。
ここでは、実際の開発現場で役立つカスタムミドルウェアのサンプルコードを充実させて解説します。
1. カスタムミドルウェアの基本と実用例
まずは、ユーザーが利用停止(banned)状態の場合に、ログイン後の画面へアクセスさせず、専用の通知ページへリダイレクトするミドルウェアのサンプルを見ていきます。
1-1. 利用停止ユーザーのチェックミドルウェア(CheckUserStatus)
作成コマンド:
php artisan make:middleware CheckUserStatus
生成されるファイル:
app/Http/Middleware/CheckUserStatus.php
サンプルコード:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CheckUserStatus
{
/**
* Handle an incoming request.
*
* ユーザーが利用停止状態の場合、専用の通知ページへリダイレクトする
*
* @param \Illuminate\Http\Request $request 現在の HTTP リクエスト
* @param \Closure $next 次に実行すべき処理
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
// リクエスト前の処理
$user = Auth::user();
// ログイン済みかつ利用停止状態の場合(例として、Userモデルに isBanned() メソッドがある)
if ($user && $user->isBanned()) {
// 利用停止の通知ページへリダイレクト
return redirect()->route('banned.notice');
}
// 次のミドルウェアまたはコントローラにリクエストを渡す
$response = $next($request);
// レスポンス後の処理:レスポンスヘッダーにカスタム情報を追加
$response->headers->set('X-User-Status', $user ? 'active' : 'guest');
return $response;
}
}
補足:
-
Auth::user()
を利用して現在のユーザー情報を取得。 - ユーザーがログインしている場合に、
isBanned()
(Userモデルに実装していると仮定)で利用停止状態かチェック。 - 利用停止の場合、
redirect()->route('banned.notice')
で専用ページへ誘導しています。 - レスポンス後の処理で、
X-User-Status
ヘッダーを追加しているのは、後からデバッグやフロントエンド側で確認するための例です。
2. パラメータ付きミドルウェアの実用例
次に、ユーザーのロール(権限)をチェックするミドルウェアのサンプルです。
たとえば、管理者専用のルートにアクセスさせる前に、ユーザーが admin
ロールを持っているかをチェックします。
2-1. ユーザーロールチェックミドルウェア(CheckUserRole)
作成コマンド:
php artisan make:middleware CheckUserRole
生成されるファイル:
app/Http/Middleware/CheckUserRole.php
サンプルコード:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class CheckUserRole
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $role 期待するユーザーロール(例:"admin")
* @return mixed
*/
public function handle(Request $request, Closure $next, $role)
{
$user = Auth::user();
// ユーザーがログインしていない、もしくは期待するロールを持っていない場合
if (! $user || ! $user->hasRole($role)) {
// 403エラーを返すか、または特定のページへリダイレクトする
abort(403, 'この操作は許可されていません。');
}
return $next($request);
}
}
補足:
-
$role
はルート定義時にミドルウェアへ渡すパラメータです。 - ユーザーがログインしていない場合や、Userモデルに実装した
hasRole()
メソッドで期待するロールを持っていない場合は、HTTP 403 エラーを返します。 - もちろん、必要に応じてリダイレクト処理に変更することも可能です。
3. ミドルウェアの登録(Laravel 11.x ~ bootstrap/app.php)
Laravel 11.x では、ミドルウェアは bootstrap/app.php
に登録します。
以下は、グローバルミドルウェアとルートミドルウェアの登録例です。
3-1. グローバルミドルウェアの登録例
// bootstrap/app.php
$app->middleware([
// すべてのリクエストに適用するミドルウェア
App\Http\Middleware\CheckForMaintenanceMode::class,
App\Http\Middleware\CheckUserStatus::class, // 先ほど作成した利用停止ユーザーチェック
]);
3-2. ルートミドルウェアの登録例
// bootstrap/app.php
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
'role' => App\Http\Middleware\CheckUserRole::class, // パラメータ付きミドルウェア
'sample' => App\Http\Middleware\SampleMiddleware::class,
]);
4. ルート定義と実用的な使用例
実際のルート定義において、上記のミドルウェアをどのように活用するかを見てみましょう。
4-1. 利用停止ユーザーのリダイレクト例
利用停止ユーザー向けの通知ページ(例:banned.notice)があると仮定します。
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\NoticeController;
Route::group(['prefix' => 'admin'], function () {
// ログイン関連のルート(ミドルウェア不要)
Route::get('/login', [LoginController::class, 'showLoginForm'])->name('login');
Route::post('/login', [LoginController::class, 'login']);
// 通知ページ:利用停止ユーザー向け
Route::get('/banned', [NoticeController::class, 'banned'])->name('banned.notice');
// 認証済みユーザー向けのルートグループ
Route::group(['middleware' => 'auth'], function () {
// 利用停止チェックミドルウェアはグローバルに登録済み
// 管理者のみアクセス可能なルート
Route::group(['middleware' => 'role:admin'], function () {
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
});
});
});
ポイント:
-
/admin/banned
には、利用停止状態のユーザーがリダイレクトされます(CheckUserStatus
ミドルウェアが働く)。 -
/admin/dashboard
は、auth
とrole:admin
のミドルウェアが両方適用され、ログイン済みかつ管理者権限を持つユーザーのみアクセス可能です。
5. サービスプロバイダの自動登録とその違い
Laravel 11.x では、サービスプロバイダを作成すると自動的に bootstrap/providers.php
に登録されるようになりました。
サービスプロバイダは、アプリケーション起動時に一度だけ実行され、以下のような初期化処理を担当します。
5-1. サービスプロバイダ作成の例
php artisan make:provider CustomServiceProvider
生成されたサービスプロバイダは、以前は手動で config/app.php
の providers
配列に追加する必要がありましたが、Laravel 11.x では自動で bootstrap/providers.php
に登録されます。
サービスプロバイダとミドルウェアの違い:
-
ミドルウェア:
→ 各リクエストごとに実行される処理(例:認証、権限チェック、CSRF 保護)
→bootstrap/app.php
でグローバルまたはルート単位で登録 -
サービスプロバイダ:
→ アプリケーション起動時の初期化処理(例:サービスバインディング、イベントリスナー登録)
→ 作成時に自動でbootstrap/providers.php
に登録され、アプリ全体の基盤を構築
6. まとめ
-
カスタムミドルウェアの作成:
Artisan コマンドで生成し、handle
メソッド内でリクエスト前後の処理を実装。
実用例として、利用停止ユーザーのリダイレクト(CheckUserStatus
)やパラメータ付きのロールチェック(CheckUserRole
)を紹介。 -
Laravel 11.x の登録方式:
ミドルウェアはbootstrap/app.php
でグローバルおよびルートミドルウェアとして登録。
サービスプロバイダは作成時に自動でbootstrap/providers.php
に登録され、手動設定が不要に。 -
実用的なサンプルコード:
ルート定義例やコントローラと連携した利用例を充実させ、実際のアプリケーションでの利用イメージを明確化。
これらを活用することで、堅牢で保守性の高い Laravel アプリケーションを構築できるでしょう。
ぜひ、自分のプロジェクトに合わせたカスタムミドルウェアを作成し、柔軟なリクエスト制御を実現してください!
参考リンク
- Laravel 11 公式ドキュメント - Middleware
- Laravel 11 公式ドキュメント - Service Providers
- Laravel 11 公式ドキュメント - Routing
以上、実用的なカスタムミドルウェアの作成と活用例についての解説でした。
ご質問やコメントがあれば、お気軽にお寄せください!