【Laravel11 認証機能】Adminユーザの作成 2. ガード・プロバイダ設定 &ミドルウェア作成

Laravel 認証機能 – adminガード・プロバイダ設定 & 専用ミドルウェア作成

前回は管理者ユーザ用のデータベース設定とテストデータの投入を行いました。

今回は管理者ユーザのログインに必要なガード & プロバイダの設定と、ユーザ権限の違いによるアクセス制御を行うためのミドルウェア(middleware)の作成を行います。

Laravelの「ガード」と「プロバイダ」について、以下の記事も併せてお読みいただくと、本記事の内容がより理解いただけるようになるかと思います。

【Laravel】認証機能におけるガードとプロバイダの仕組みを理解しよう

環境: Laravel 11, PHP 8.3.14

管理者用ガード & プロバイダ設定

管理者ユーザ認証用のガードとプロバイダの設定を行います。

各種設定の意味や役割、ガード & プロバイダの役割等は別途記事を参考にしてください。

config/auth.php

1. 管理者用guard作成

guardsと定義された箇所のwebに続けて、新たにadminを追加します。

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'admin' => [ // 管理者用ガード
            'driver' => 'session',
            'provider' => 'admins',
        ],
    ],

2. 管理者用provider作成

providersの定義にもadminを追加します。

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => env('AUTH_MODEL', App\Models\User::class),
        ],

        'admins' => [ // 管理者用プロバイダ
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ],
    ],

modelの箇所に今回作成したAdminモデルを指定することで、adminsテーブルのユーザデータが認証の対象となります。

3. パスワードリセットの設定(任意)

パスワードリセット機能も、通常ユーザと同様有効にしておきます。

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
            'expire' => 60,
            'throttle' => 60,
        ],
        'admins' => [ // 管理者用パスワードリセット設定
            'provider' => 'admins',
            'table' => 'password_reset_tokens',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

ミドルウェア(Middleware)の作成

後で作成する管理者用ユーザ専用ページへアクセス制御を行うためのミドルウェアを作成します。

このミドルウェアが適用されたURLにアクセスしたユーザが、adminガードで認証されていなければトップページ(/)へリダイレクトさせます。

AdminMiddleware(管理者用ミドルウェア)

作成コマンド:
php artisan make:middleware AdminMiddleware

app/Http/Middleware/AdminMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\Auth;

class AdminMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next)
    {
        if (!Auth::guard('admin')->check()) {
            return redirect('/');
        }

        return $next($request);
    }
}

CustomGuestMiddleware (カスタムguestミドルウェア)

Laravelにデフォルトで存在するguestミドルウェアは、web ガード(通常ユーザ)の未認証状態のみチェックします。

そのため、今回作成した管理者用ガード(admin)のログイン状態は無視されます。

通常ユーザと管理者用ユーザどちらの権限でもログインしていないことを判定するための専用のミドルウェアを別途作成します。

このミドルウェアが適用されたURLにアクセスしたユーザが、デフォルトガード(web)またはadminガードの両方で認証されていない、つまりゲストの場合はトップページ(/)へリダイレクトさせます。

作成コマンド:
php artisan make:middleware CustomGuestMiddleware

app/Http/Middleware/CustomGuestMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\Auth;

class CustomGuestMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next)
    {
        if (Auth::check() || Auth::guard('admin')->check()) {
            return redirect('/');
        }

        return $next($request);
    }
}

AuthenticatedMiddleware(ログイン済みミドルウェア)

デフォルトのauthミドルウェアも、guestミドルウェアと同様、デフォルトのwebガードの認証状態しかチェックをしないため、通常ユーザまたは管理者ユーザのいずれかの権限で認証済みを確認するためのミドルウェアを新たに作成します。

デフォルトガード(web)またはadminガードのいずれかで認証チェックを行い、どちらにも該当しなければトップページ(/)へリダイレクトさせます。

作成コマンド:
php artisan make:middleware AuthenticatedMiddleware

app/Http/Middleware/AuthenticatedMiddleware.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthenticatedMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next)
    {
        if (Auth::check() || Auth::guard('admin')->check()) {
            return $next($request);
        }

        return redirect()->route('login');
    }
}

ミドルウェアの登録

作成した3つのミドルウェアを使用可能にするためにbootstrap/app.phpに登録します。

bootstrap/app.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use App\Http\Middleware\AdminMiddleware;
use App\Http\Middleware\CustomGuestMiddleware;
use App\Http\Middleware\AuthenticatedMiddleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            'admin' => AdminMiddleware::class,
            'custom.guest' => CustomGuestMiddleware::class,
            'authenticated' => AuthenticatedMiddleware::class
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

withMiddlewareのクロージャーの中で変数middlewareに対して、aliasという関数を実行してその中に、ミドルウェアの利用名称と作成したミドルウェアクラス本体をマッピングして定義します。

この仕様はLaravel 11で大きく変わった点のうちの一つであるようです。

参考
https://www.socym.co.jp/download/1408/Laravel11_Support_Guide_1_0.pdf
https://laravel.com/docs/11.x/middleware#middleware-aliases


ガード & プロバイダの設定と新しいミドルウェアの準備を行いましたので、次回はこれらの仕組みを利用して管理者ユーザ機能を完成させていきます。

Follow me!