【Laravel】ミドルウェアとは:作成方法や書き方、使い道について

時計 2024.05.03 / 時計

【Laravel】ミドルウェアとは:作成方法や書き方、使い道について

記事ではLaravelにおける、ミドルウェアについて詳しく解説していきます。

ミドルウェアとはリクエストをコントローラーに渡す前やリクエストをユーザーに送信する前に特定の処理を行う仕組みです。主にユーザー認証や権限による認可、セッション管理、バリデーションなどに利用されます。

本記事を通して、Laravelのミドルウェアの作成方法書き方、使い道などについて理解を深めてください。

Laravelのミドルウェア

ミドルウェアとは(Middleware)

ミドルウェアとはリクエスト/レスポンス処理の前後でフックを加える仕組みです。

IT用語の確認

フック(hook)とはプログラムの特定箇所にユーザーが作成した処理を追加して実行する仕組みのこと

Laravelのミドルウェアでは次図のようにHTTPリクエストがアプリケーションのコア部分(コントローラー)に到達する前やレスポンスがクライアントに送信される前に使用されます。

Laravel:処理の流れ

コントローラーの前のミドルウェアをBefore Middleware、後ろに配置されるミドルウェアをAfter Middlewareと呼びます。

ミドルウェアのメリット

ミドルウェアを利用する理由として「処理の共通化」があります。
各コントローラーで重複する処理がある場合、それをミドルウェアで共通化することで可読性の向上やコントローラーの肥大化を抑えることができます。

ミドルウェアのメリットを簡単にまとめると次の通りです。

Laravelのミドルウェアのメリット
  • 特定の機能をアプリケーション全体で再利用できる
  • コントローラーやルートで共通して必要な機能を重複して記述する必要がなくなる
  • 効率的に認証や認可、XSS防御などのチェックを行える
  • 条件に基づいてリクエストを処理する条件付き処理を簡単に実装できる

上記のメリットはミドルウェアのメリットのほんの一部です。Laravelのミドルウェアを利用することでコードの再利用性やアプリのセキュリティ、開発速度などが向上します。

ミドルウェアの使い道

ミドルウェアの用途としては以下に記すように認証やセッション管理、CSRF保護、フィルタリング、バリデーションなどがあります。

ミドルウェアの使用用途
  • 認証と認可
  • ログ記録
  • リクエストの修正
  • レスポンスの変更
  • セッション管理
  • レート制限

認証と認可

リクエストがコントローラーに行く前にミドルウェアによるユーザー認証やアクセスする権限があるかどうかを確認させることができます。

Laravelに標準で用意されているauthミドルウェアでは、ログインしていないユーザーをログインページにリダイレクトすることができます。

ログ記録

アクセス管理や情報収集用のログを取るためにミドルウェアは利用されることもあります。

ミドルウェアを使ってリクエスト内容やユーザーの行動をログに記録することが可能です。

リクエストの修正

ユーザーからのリクエストを希望する形に修正したりサニタイズ処理するためにミドルウェアを利用することができます。

レスポンスの変更

ユーザーにレスポンスを送信する際に、送信内容の修正やヘッダーの追加といった操作をミドルウェアで実現することができます。

セッション管理

ユーザーのセッションに基づいてリクエストを処理するか判別するような、セッション管理をミドルウェアで実装することが可能です。

レート制限

ミドルウェアでレート制限を設けることができます。レート制限とは特定の時間内でユーザーやIPアドレスごとに許可されるリクエストの数を制限する手法です。

過度のリクエストによるサーバーの過負荷を防ぎ、サービスの乱用を防止する目的で使用されます。

ミドルウェアの作成方法

Laravelでミドルウェアを作成する際は以下の流れで操作します。

  • artisanコマンドでミドルウェアクラスの生成
  • handleメソッドの編集
  • Kernel.phpにミドルウェアの登録
  • ルートにミドルウェアを適用

上記の各操作について次項より詳しく解説していきます。

artisanコマンドでミドルウェアクラスの生成

まずartisanコマンドを利用してミドルウェアクラスを生成します。

構文

php artisan make:middleware ミドルウェア名

例えば以下のようにコマンドを実行します。

php artisan make:middleware AdminAllowMiddleware

上記コマンドを実行するとapp/Http/Middleware内に「AdminAllowMiddleware.php」が作成されます。中身は以下のように記述されています。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AdminAllowMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request);
    }
}

use Closure;ではClosureクラスをインポートして$nextを利用できるようにしています。

return $next($request);ではリクエストを次のステップである対象のコントローラーにリクエストを渡しています。

handleメソッドの編集

次に生成されたミドルウェア内のhandleメソッドに具体的な処理を記述します。

コントローラーにリクエストを渡す前のBeforeMiddlewareの処理(リクエスト前処理)はreturn $next($request);より前に記述します。

class AdminAllowMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        // ここにリクエスト前処理を記述する
        return $next($request);
    }
}

リクエスト後処理のAfterMiddlewareはreturn $next($request);の後に記述します。

class AdminAllowMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request);
// ここにリクエスト後処理を記述する
    }
}

ここではusersテーブルのroleフィールドが「admin」のユーザーのみリクエストを実行する処理を記述します。

public function handle(Request $request, Closure $next): Response
{
    if(auth()->user()->role == 'admin') {
        return $next($request);
    }

    return redirect()->route('home'); //admin以外はhomeにリダイレクトする
}

Kernel.phpにミドルウェアの登録

ミドルウェアを作成したら、ミドルウェアをアプリケーション内で利用できるようにapp/Http/Kernel.php内の$middlewareAliases(または$routeMiddleware)に追記します。$middlewareAliasesには特定のルートやルートグループに適用したいミドルウェアを指定する箇所です。

protected $middlewareAliases = [
    …
    'admin' => \App\Http\Middleware\AdminAllowMiddleware::class,
];
POINT

すべてのHTTPリクエストに対して適用されるようにしたいミドルウェアは「$middleware」に追加しましょう

ルートにミドルウェアを適用

最後に登録したミドルウェアをルートに対して適用します。ルートに適用する場合は対象のルートに以下コードを追記します。

構文

->middleware('ミドルウェア1', 'ミドルウェア2', …)

例えば以下のようにadminミドルウェアをルートに適用させます。

Route::get('register', [RegisteredUserController::class, 'create'])
    ->middleware('admin')
    ->name('register');

上記により、roleがadminのユーザーのみがregisterにアクセスすることができるようになります。

関連記事:【Laravel】管理者を作成してアクセス制限を行う

ルーティンググループ全体にミドルウェアを適用する場合は以下のように記述できます。

Route::middleware(['admin'])->group(function () {
    //
})