【Laravel】Gateを使ってロールを判定する
はじめに
Laravelでは以下のような場合に便利なGateという仕組みを提供しています。
- 特定のユーザーに対して特定のルートを許可したい場合
 - blade内で特定の項目を表示したい場合
 
今回はそんなGateの利用方法について簡単にまとめていきたいと思います。
参考
使用するカラムを追加
ユーザーテーブルに'role_id'カラムを追加します。
今回はrole_idが10の場合を管理者ユーザー、1の場合を一般ユーザーとします。
Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->integer('role_id'); //10:管理者ユーザー 1:一般ユーザー
            $table->string('name');  
            $table->string('email')->unique();
            $table->string('password');
            $table->timestamps();
        });
Gateを設定
app/Providers/AuthServiceProvider.phpを編集します。
以下では、ログインしたユーザーのロールを判定するGateを'boot'メソッド内に定義しています。
第一引数にはGateの制限の名前(自由)、第二引数にはクロージャを設定します。
クロージャの戻り値はtrueまたはfalseを設定します。
今回は管理者ユーザーを'admin'、一般ユーザーを'general'としています。
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        // 'App\Model' => 'App\Policies\ModelPolicy',
    ];
    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        // 管理者ユーザー
        Gate::define('admin', function (User $user) {
            return ($user->role_id === 10);
        });
        // 一般ユーザー
        Gate::define('general', function (User $user) {
            return ($user->role_id === 1);
        });
    }
}
管理者ページを作成
今回はresources/views/page/admin配下にindex.blade.phpを作成することにします。
    <h1>管理者ページ</h1>
app/Http/Controllers/User配下のUserController.phpに管理者ページを表示するメソッドを追加します。
 public function showAdminPage()
    {
        return view('page.admin.index');
    }
ルーティングを設定
routes/web.phpを以下のように編集します。
今回の場合、AuthServiceProviderで'admin'と判定されたユーザーのみ'user/admin'へのアクセスを許可しています。
※'admin'以外のユーザーがアクセスすると403のレスポンスが返ってきます。
 Route::prefix('/user')->group(function () {
    Route::get('/profile', 'User\UserController@showProfile');
    // 管理者ユーザーのみ
    Route::group(['middleware' => ['auth', 'can:admin']], function () {
        Route::get('/admin', 'User\UserController@showAdminPage');
    });
});
これで管理者ユーザーのみアクセスできる管理者ページを作成することができました。
blade内で使用する場合
上記ではロールを定義してページへのアクセスを制限しましたが、blade内でもロールに応じた出し分けをすることができます。
今回はヘッダーで管理者ユーザーにのみ管理者ページへ遷移できるボタンを表示します。
以下のように@can('AuthServiceProviderで定義した制限の名前')とすることで簡単に出し分けができます。
@can('admin')
  <a href="/user/admin" class="auth-btn auth-btn--text">
     管理者ページへ
  </a>
@endcan
Discussion