Laravel11でGate使ってUserをroleでルート分岐させるゾ
UserとAdmin分けたいんだけど、大規模なサイトじゃないからAdmin1人だし、それならマルチ認証でつくるほどでもないよね?ってときあるよね。
そういう時はUserモデルにroleっていう権限カラム持たせて、その値で判断しよう。
そして、その値で、Adminだけの管理ページに飛ばせば、普通のuserはページに入れない。
こんな感じの構成を作ってみたいと思います。
User認証用に、Breezeがインストールされている前提です。
マイグレーションでUserモデルにカラム追加
UserとAdminを区別するために、Userテーブルにroleカラムを作成します。
値は、普通にStringで(user or admin)でいきます。
ターミナルに次のコードを入力します。
php artisan make:migration add_users_table_1column --table=users
これで追加用のテーブルが作成されました。
中身に次のコードを入力します。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('role')->default('general')->comment('権限名')->after('password');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('role');
});
}
};
これは、usersテーブルのpasswordカラムの下に、roleカラムを作ってという内容になります。
カラムのデフォルト値はgeneralで、adminにしたいuserだけadminとPHPMyAdminなどで手動更新します。
また、SeederでAdmin用データを入れても良いです。
ファイルができたら、次のコードでマイグレーションします。
php artisan migrate
これでデータベースのusersテーブルにroleカラムができました。
usersの中でAdminにしたい人のroleをadminに変えておいてください。
ProvidersにAuthServiceProviderを作ろう
laravelの11になってからProvidersにファイルはありません。
ターミナルから自分で作る必要があります。
php artisan make:provider AuthServiceProvider.php
これでapp/providersの中にAuthServiceProviderが作成されます。
以下のコードをコピーして貼り付けます。
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The model to policy mappings for the application.
*
* @var array<class-string, class-string>
*/
protected $policies = [
//
];
public function boot()
{
$this->registerPolicies();
Gate::define('admin', function (User $user) {
if ($user->role === 'admin') {
return true;
} else {
return false;
}
});
}
}
これは、認証時にGateにadminを設定しています。
Userモデルのroleがadminならば、Gateにadminを設定して返す。それ以外は返さない。
といった感じの内容になってます。
Laravel10まではここに書くだけで良かったのですが、Laravel11になってからは、このAuthServiceProvider.php自体をアプリスタート時に読み込ませなければいけません。
bootstrap/providers.phpにこのファイルを追加する必要があります。
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
];
ログイン時にAdmin用のダッシュボードにとばしたい
app/Http/Controllers/Authに認証用のファイルが入っています。
この中で、AuthenticatedSessionController.phpがログイン用のファイルとなっています。
storeメソッドがログインリクエストになりますので、ここで、認証が済みセッションが再生成されたあと、ダッシュボードに飛ぶように書いてありますが、これをGateでadminに設定されていたらadminダッシュボードに飛ばすように追加で修正します。
<?php
use Illuminate\Support\Facades\Auth;//追加
use Illuminate\Support\Facades\Gate;//追加
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
if (Gate::allows('admin', Auth::user())) {
return redirect()->intended(route('admin.dashboard', absolute: false));
}
return redirect()->intended(route('dashboard', absolute: false));
}
これで処理は完了です。
dashboardファイルを作る
Adminのときに開く専用のダッシュボードファイルを作ります。
resources/views にdashboard.blade.phpがあるので、これをコピーして、admin-dashboard.blade.phpにリネームします。
中に<x-app-layout>と記載があると思うのでこれをx-admin-layoutに修正します。
h1のWelcome to your dashboardと書かれた文字のあたりにわかりやすくADMINと書いておきます。
次に、layoutsフォルダの中のapp.blade.php/navigation.blade.phpをそれぞれコピーして、admin.blade.php/admin-navigation.blade.phpに修正します。
admin.blade.phpの中にある@include('layouts.navigation')を@include('layouts.admin-navigation')に修正します。
admin-navigation.blade.phpの中のroute('dashboard')はroute('admin.dashboard')に変更します。
最後に、app/ViewフォルダのAppLayout.phpをコピーして、Adminlayout.phpに直し以下のコードをコピーします。
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use Illuminate\View\View;
class AdminLayout extends Component
{
/**
* Get the view / contents that represents the component.
*/
public function render(): View
{
return view('layouts.admin');
}
}
ルートファイルに分岐を記載する
処理は完成したのでroutes/auth.phpでRouteを記入していきます。
ログインは共通なので、そのあとのログイン後にいくURLを記入していきます。
<?php
Route::get('/admin/dashboard', function () {
return view('admin-dashboard');
})->middleware(['auth', 'can:admin', 'verified'])->name('admin.dashboard');
最後に構成をクリアします。
php artisan optimize
以上で、終了です。
これで、通常のログイン画面からadminでログインして、Admin専用ダッシュボードが表示されていれば成功です。
ここから先は、prefixやnameでadminを分けて、routeファイル自体も分けて処理をしていくと便利だと思います。
お疲れ様でした🤗
Discussion