Laravel-permissionは、Laravelアプリケーションにロールベースのアクセス制御(Role-Based Access Control, RBAC)を追加するためのパッケージです。このパッケージをLaravelプロジェクトにインストールする手順は以下の通りです
Laravel-permissionの導入
composerでインストール
Laravelプロジェクトのルートディレクトリで以下のコマンドを実行して、Laravel-permissionパッケージをインストールします。
composer require spatie/laravel-permission
パッケージプロバイダの登録
Laravel 5.5以降では、パッケージのサービスプロバイダは自動的に登録されますが、手動で行う場合は、config/app.php ファイルに以下のサービスプロバイダを追加します。
何故か自動登録されていなかったので、下記のように登録しました。
'providers' => [
// 下記を追加
Spatie\Permission\PermissionServiceProvider::class,
];
マイグレーションファイルの公開
パッケージのマイグレーションファイルをプロジェクトに公開します。
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
DBテーブルの生成
次のコマンドを実行し、パーミッションとロール用のDBを登録します。
php artisan migrate
5つのテーブルが生成されました。
モデルの設定
ユーザーモデル(通常は App\Models\User)に Spatie\Permission\Traits\HasRoles トレイトを追加します。これにより、ユーザーにロールと権限を割り当てるメソッドが使えるようになります。
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
// ...
}
Middlewareに登録
Kernerl.phpに下記を追加します。
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
// その他のMiddleware ...
// Laravel-permissionのミドルウェアを追加
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
];
ロールの作成
ロールはユーザーの役割を表します(例えば「管理者」、「エディター」など)。ロールを作成するには、Role モデルを使用します。以下は、ロールを作成する基本的な方法です。
コマンドラインからの作成
- Tinkerを使用して、コマンドラインから直接ロールを作成することができます。Tinkerを開始するには、php artisan tinker を実行します。
- 次に、Roleモデルを使用してロールを作成します:
use Spatie\Permission\Models\Role;
Role::create(['name' => 'admin']);
Role::create(['name' => 'editor']);
シーダーを使用した作成
- データベースシーダーを使用して、ロールを作成することもできます。これは初期データのセットアップ時に便利です。
- database/seeds ディレクトリにシーダーファイルを作成し、その中でロールを定義します
php artisan make:seeder RoleSeeder
下記の様に記述します。
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
class RoleSeeder extends Seeder
{
public function run()
{
Role::create(['name' => 'admin']);
Role::create(['name' => 'manager']);
Role::create(['name' => 'team_manager']);
Role::create(['name' => 'project_manager']);
Role::create(['name' => 'moderator']);
Role::create(['name' => 'editor']);
Role::create(['name' => 'subscriber']);
}
}
このシーダーを実行するには、Artisanの db:seed コマンドを使用し、–class オプションでシーダークラスを指定します。
php artisan db:seed --class=RoleSeeder
パーミッションの作成
同様に、Permission モデルを使用してパーミッションを作成します。
use Spatie\Permission\Models\Permission;
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
パーミッションの作成
パーミッションは、ユーザーが実行できる特定のアクションを表します(例えば「記事の編集」、「記事の削除」など)。パーミッションの作成プロセスは、ロールの作成と似ています。
コマンドラインからの作成
同様に、Tinkerを使用してパーミッションを作成できます
use Spatie\Permission\Models\Permission;
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
シーダーを使用した作成
パーミッションもシーダーを介して作成できます。ロールの作成と同じように、シーダーファイルを作成し、パーミッションを定義します
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
class PermissionSeeder extends Seeder
{
public function run()
{
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
}
}
ロールとパーミッションの割り当て
ロールをユーザーに割り当てる
ロールとパーミッションを作成した後、これらをユーザーに割り当てることができます。例えば、ユーザーに「管理者」ロールを割り当てるには
$user = User::find($userId); // 特定のユーザーを取得
$user->assignRole('admin');
パーミッションをロールに割り当てる
givePermissionTo メソッドを使用して、特定のロールにパーミッションを割り当てます。
$role = Role::findByName('editor');
$role->givePermissionTo('edit articles');
パーミッションをユーザーに直接割り当てる
ユーザーに直接パーミッションを割り当てることもできます。
$user->givePermissionTo('edit articles');
チェックと認可
ロールとパーミッションのチェック
ユーザーが特定のロールやパーミッションを持っているかどうかをチェックできます。
$user->hasRole('admin');
$user->hasPermissionTo('edit articles');
ポリシーと認可
Laravelの認可機能を使用して、特定のアクションに対するユーザーの権限をチェックします。ポリシークラスを作成し、ロールやパーミッションに基づいてアクセス制御を行います。
アクセス制御の実装
ミドルウェアを使用したアクセス制御
ルートやコントローラーのアクションで、特定のロールやパーミッションが必要な場合、ミドルウェアを使用してアクセス制御を行います。
Route::group(['middleware' => ['role:admin']], function () {
Route::get('/admin', 'AdminController@index');
});
ビューでのアクセス制御
Bladeテンプレート内でユーザーが特定のロールやパーミッションを持っているかどうかに基づいて、コンテンツの表示を制御します。
@role('admin')
// 管理者専用のコンテンツ
@else
// その他のユーザー向けのコンテンツ
@endrole
ポリシーでのアクセス制御
Laravelのポリシーメソッドを使用して、特定のアクションに対するアクセス制御を行います。
以下に、ポリシーでのアクセス制御について詳しくご紹介します。
ポリシーの作成と登録
ポリシーの生成
Artisanコマンドを使用して新しいポリシーを生成します。例えば、Article モデルに対するポリシーを生成する場合は以下のようになります。
php artisan make:policy ArticlePolicy --model=Article
ポリシーの登録
ポリシーをLaravelの認可システムに登録します。これは通常 AuthServiceProvider の中で行われます。
// app/Providers/AuthServiceProvider.php
protected $policies = [
'App\Models\Article' => 'App\Policies\ArticlePolicy',
];
ポリシーの定義と使用
ポリシーのメソッドの記述
ポリシークラス内で、モデルに対する各種操作を認可するためのメソッドを定義します。
// app/Policies/ArticlePolicy.php
public function update(User $user, Article $article)
{
return $user->id === $article->user_id;
}
この例では、update メソッドが定義されており、ユーザーがその記事の所有者である場合にのみ、更新操作を許可しています。
コントローラーでのポリシーの使用
コントローラー内でポリシーを使用してアクションの認可を行います。
public function edit($id)
{
$article = Article::find($id);
// ポリシーをチェック
$this->authorize('update', $article);
// ...
}
authorize メソッドは、ユーザーが指定されたアクションを実行できない場合に、自動的に Illuminate\Auth\Access\AuthorizationException を投げます。
Bladeテンプレートでのポリシーの使用
Bladeテンプレート内でポリシーを使用して、特定のUI部品を表示するかどうかを制御します。
@can('update', $article)
<!-- 更新ボタンを表示 -->
@endcan
注意点
- ポリシーは、特定のモデルに対するユーザーのアクションを認可するために使われます。そのため、一般的にはモデルクラスごとにポリシーを作成します。
- ポリシー内の各メソッドは、特定のアクション(例えば作成、閲覧、更新、削除など)を実行するための認可ロジックを含みます。
- ポリシーは主にコントローラーとビューで使用されますが、場合によってはルートやミドルウェアでも利用可能です。
- ポリシーのメソッドは、必要に応じて追加のパラメータを受け取ることができますが、通常は最初のパラメータが認証されたユーザー( User $user )、次のパラメータが関連するモデルのインスタンスです。
コメント