カテゴリー: BackEnd

Laravelの認可機能Gateを使ってみた

はじめに

Laravelには認可機能を簡単に実装出来るGateという機能が用意されているので使ってみました。

やる事

よくあるユースケースとして、ユーザー毎に画面の閲覧権限とPOST権限を作ってみたいと思います。

デフォルトで用意されているusersテーブルにint型でroleというカラムを追加して、
1: ディレクター 2: マネージャー 3: スタッフ
の形で実装したいと思います。

Gate

登録

AuthServiceProvider.phpにGateファサードを利用して以下の様に認可機能の登録します。

Gateにはconfig/auth.phpで指定している認証用のモデル(デフォルトはUserモデル)がフレームワークによって常に渡されます。

 public function boot()
    {
        $this->registerPolicies();

        // 第一引数には、abilityと呼ばれる認可種類名を渡す
     // クロージャには、認証しているユーザーモデルが渡される
        Gate::define('view', function ($user) {
            // roleカラムがデレクター  or マネージャーの場合認可
            return (in_array($user->role, [RoleEnum::DIRECTOR->value, RoleEnum::MANAGER->value]));
        });

        Gate::define('approve', function ($user) {
            // roleカラムがディレクターの場合認可
            return ($user->role == RoleEnum::DIRECTOR->value);
        });
    }

roleの値は分かりやすくEnumで表現してます。

<?php

namespace App\Enums;

enum RoleEnum: int

{
    case DIRECTOR = 1;
    case MANAGER = 2;
    case STAFF = 3;
}

利用

Controllerで閲覧とPOSTメソッド時に登録したGateを利用してログインユーザーの認可を行います。
認可には、Gateファサードのallowsメソッドの中で登録したability名を引数に渡します。

class GateController extends Controller
{
    public function index(Request $request) {
        // ディレクター or マネージャーの場合認可
        if (!Gate::allows('view')) {
            abort(403);
        }

        return Inertia::render('Gate/Index');
    }

    public function post(Request $request) {
        // ディレクターの場合のみ認可
        if (!Gate::allows('approve')) {
            abort(403);
        }

        return Inertia::render('Gate/Index', [
            'postResult' => true
        ]);
    }
}

この状態で、ディレクター権限を持つユーザーでログインすれば画面表示から承認まで行う事が出来ますが、マネージャー権限のユーザーでは画面表示まで、スタッフ権限のユーザー何も出来ず403が返されます。

Policy

上記例では権限設定を2つしか設定していませんが多くの権限を設定する場合には、権限管理を行うPolicy機能を利用する事が出来ます。

Policyファイルを作成します。

php artisan make:policy ApprovalPolicy

次に各権限の設定を書きます

class ApprovalPolicy
{
    use HandlesAuthorization;

    // 閲覧権限
    public function view(User $user)
    {
        // roleカラムがディレクター or マネージャーの場合認可
        return in_array($user->role, [RoleEnum::DIRECTOR->value, RoleEnum::MANAGER->value]);
    }

    // 承認権限
    public function approve(User $user)
    {
        // roleカラムがディレクターの場合認可
        return $user->role == RoleEnum::DIRECTOR->value;
    }
}

作成したApprovalPolicyを利用してAuthServiceProvider.phpで以下の様にスッキリとGateを登録する事が出来ます。

 public function boot()
 {
        $this->registerPolicies();

        Gate::define('view', [ApprovalPolicy::class, 'view']);
        Gate::define('approve', [ApprovalPolicy::class, 'approve']);
 }

ミドルウェアでの使用

ControllerではなくMiddlerWareでGateの設定をする事も可能です。

デフォルト実装されているIlluminate\Auth\Middleware\AuthorizeApp\Http\Kernelクラスでcanキーに割当されています。その為、ルーティングで以下の様に書くと、ControllerにGate::allowsを書かなくても同じ結果が得られます。

Route::prefix('gate')->name('gate.')->group(function () {
    Route::get('/', [GateController::class, 'index'])->name('index')->middleware('can:view'); // ディレクター or マネージャーのみ
    Route::post('/approve', [GateController::class, 'approve'])->name('approve')->middleware('can:approve'); // ディレクターのみ
});

さいごに

Gate機能を利用する事で簡単に認可機能を実装する事が出来ます。認可機能を実装する際には利用してみたいと思います。

おすすめ書籍

Yossy

シェア
執筆者:
Yossy
タグ: phplaravel

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

4週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前