laravel12.laravel_034
R e i - D r e a m
for Laravel
TOP > Laravel Ver.12 > 認証処理(ミドルウェア)
Guest
login

最終投稿日:2026年3月10日

ミドルウェア
ミドルウェア
ミドルウェアというより『インターセプター』の方が分かりやすいかも。
つまりコントローラの処理を一時【奪い取る】機能です。
作成方法は[artisan]コマンドを使うと楽チンで、以下のような書式となります。
 php artisan make:middleware {ミドルウェア名}
それでは名前を「Initialize」として作成してみましょう。
ターミナル

C:\~\laravel_12>php artisan make:middleware Initialize
    INFO Middleware [C:\xampp\htdocs\main\laravel_12\app\Http\Middleware\Initialize.php] created successfully.

C:\~\laravel_12>

「~\app\Http\Middleware\Initialize.php」が作成されました。
初期状態は以下の様になります。
Initialize.php

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class Initialize {
    public function handle(Request $request, Closure $next): Response {
        return $next($request);
    }
}

それではこの「Initialize」を使って、コントローラの処理を奪ってみましょう。
「~\routes\web.php」で設定します。
web.php

Route::group(['middleware' => 'App\Http\Middleware\Initialize::class'], function(){
    Route::get('/hoge', [App\Http\Controllers\HogeController::class, 'index'])->name('hoge.index');
});

今回はGET遷移で、アドレス「~/hoge」をミドルウェアの対象としました。
この様に、既存のルート設定をミドルウェア定義の中にポイっと入れるだけです。
この段階では画面にアクセスしても何も起こりません。
では先ほどの「Initialize.php」に以下コードを追記してみましょう。
Initialize.php

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class Initialize {
    public function handle(Request $request, Closure $next): Response {
        var_dump("OK");exit;
        return $next($request);
    }
}

画面にアクセスすると表示が『string(2) "OK" 』となりましたね。
まさに「HogeController」の処理が奪われた事が理解できたと思います。
もう少しコードを変形させてみましょう。
以下の様にしてみてください。
return $next($request);

$response = $next($request);
return $response;
このコードの意味は、変数「$response」に格納しているのが「HogeController」の処理結果となります。
そして「return $response;」で画面レンダリングをしています。
つまりコントローラ処理の【前後】をインターセプトする事が可能となります。
「Initialize」「HogeController」に『echo』を仕込むと処理の順番が確認できると思います。
複数のミドルウェアを使う
インターセプトは何も1回だけではありません。
何個だっていけちゃいます。
試しに同じ内容のミドルウェア『Initialize_second.php』を作成し、それぞれ以下の様な「echo」を入れてみます。
Initialize.php

class Initialize {
    public function handle(Request $request, Closure $next): Response {
        echo "Initialize [Start] ⇒ ";
        $response = $next($request);
        echo "Initialize [End] ⇒ ";
        return $response;
    }
}

Initialize_second.php

class Initialize_second {
    public function handle(Request $request, Closure $next): Response {
        echo "Initialize_second [Start] ⇒ ";
        $response = $next($request);
        echo "Initialize_second [End] ⇒ ";
        return $response;
    }
}

HogeController.php

public function index(Request $request) {
    echo "HogeController ⇒ ";
    ~ 省略 ~
}

最後にルートに新しいミドルウェアを設定します。
web.php

Route::group(
    ['middleware' => [
            'App\Http\Middleware\Initialize::class',
            'App\Http\Middleware\Initialize_second::class',
        ]
    ], function(){
    Route::get('/hoge', [App\Http\Controllers\HogeController::class, 'index'])->name('hoge.index');
});

それでは画面を表示してみましょう。
以下の様な出力になったハズです。
Initialize [Start] ⇒ Initialize_second [Start] ⇒ HogeController ⇒ Initialize_second [End] ⇒ Initialize [End] ⇒
ミドルウェアを複数使用した場合は「入れ子」状態となります。
設定方法色々
今まではルート(web.php)にミドルウェアの定義をしてきました。
この記述方法は、ほとんど全てのルートが同じミドルウェアに処理される場合はソースとして見やすいですが、
ルートによって様々なミドルウェアを使用する場合は、ちょっと見苦しいです。。
例えばミドルウェアが3個あり、以下の様な設定にした場合はどうでしょう?
web.php

Route::group(
    ['middleware' => [
            'App\Http\Middleware\Initialize_aaa::class',
            'App\Http\Middleware\Initialize_bbb::class',
            'App\Http\Middleware\Initialize_ccc::class',
        ]
    ], function(){
Route::get('/hoge', [App\Http\Controllers\HogeController::class, 'hoge'])->name('hoge');
});

Route::group(
    ['middleware' => [
            'App\Http\Middleware\Initialize_aaa::class',
            'App\Http\Middleware\Initialize_bbb::class',
        ]
    , function(){
Route::get('/foo', [App\Http\Controllers\HogeController::class, 'foo'])->name('foo');
});

Route::group(
    ['middleware' => [
            'App\Http\Middleware\Initialize_aaa::class',
        ]
    ], function(){
Route::get('/bar', [App\Http\Controllers\HogeController::class, 'bar'])->name('bar');
});

なかなか冗長なソースですが、ルートは《hoge|foo|bar》のたった3個です。
ちょっと見づらくないですか?
もし以下の様に記述できたらどうでしょう。
web.php

Route::get('/hoge', [App\Http\Controllers\HogeController::class, 'hoge'])->name('hoge')->middleware('M_abc');
Route::get('/foo', [App\Http\Controllers\HogeController::class, 'foo'])->name('foo')->middleware('M_ab');
Route::get('/bar', [App\Http\Controllers\HogeController::class, 'bar'])->name('bar')->middleware('M_a');

なんという事でしょう。たったの3行です!!
でも当然このままではエラーなので、「middleware」属性で設定した名前とミドルウェアをマッピングする必要があります。
「~\bootstrap\app.php」内の「withMiddleware」のクロージャ内に記述します。
~\bootstrap\app.php

~ 省略 ~
->withMiddleware(function (Middleware $middleware): void {
    $middleware->appendToGroup('M_abc', [
        App\Http\Middleware\Initialize_aaa::class,
        App\Http\Middleware\Initialize_bbb::class,
        App\Http\Middleware\Initialize_ccc::class,
    ]);
    $middleware->appendToGroup('M_ab', [
        App\Http\Middleware\Initialize_aaa::class,
        App\Http\Middleware\Initialize_bbb::class,
    ]);
    $middleware->appendToGroup('M_a', [
        App\Http\Middleware\Initialize_aaa::class,
    ]);
})
~ 省略 ~

どうでしょう?
ルートの設定とミドルウェアの設定が分離できてスッキリしました。
最後に
いかがだったでしょうか?
ミドルウェアを使うと共通の処理をコントローラから分離ができるので色々なソースがスッキリしますね。
例えばアクセスログの出力なんかうってつけです。
また、認証の独自カスタマイズをしてきましたが、カスタマイズできてない場所が1つありました。
それがまさに『Route::group(['middleware' => 'auth'], function(){』の部分です。
Laravelの組込みミドルウェアを認証制御に使っていましたが、
この機能は単純に非認証状態なら任意の画面にリダイレクトする程度です。
こんなの先ほど作成した「Initialize.php」に組み込んじゃえば良いのです!!
ログインしてコメントを残そう!!


きっぷる