【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