34
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

laravel-permissionを試す

Last updated at Posted at 2019-01-21

はじめに

Laravelでロールベースアクセス制御の割としっかりしたものを提供する必要があったので、
Laravelの拡張パッケージでお馴染みのSpatieが提供しているlaravel-permissionを試してみました。

何がどのように関係してくるのか毎回英語を読むのが怠いので残しておきます。

使ってるうちに知見が得られたら、なるべくここを更新します。
今のところは認可チェックする各ミドルウェアのテストコードを書いて動かして中身を理解したレベルです。

環境

PHP 7.2
Laravel 5.7
※動くことを確認した

インストール

composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"

テーブルがいくつか作られるので、モデルを理解しておく

image.png

rolesとpermissionsのguard_nameには、
config/auth.phpで設定しているデフォルトのguardが入る。

複数のguardを設定したい場合のガイドはあるけど、今回は必要ないので飛ばす。

model_typeにはEloquentのクラスが入る。
どうやらEloquentのポリモーフィックリレーションを使用して実装されていそうなことが判る。
(ソース見ると実際そうなってる)

テーブルについて

roles

概要

役割のマスタテーブル
予め必要なものを登録しておく

登録するものの例:

  • admin
  • operator
  • customer

など
※Super-adminとか定義できるみたいなので、その辺も念頭に置いて設定する

登録方法

$role = \Spatie\Permission\Models\Role::create(['name' => 'operator']);

model_has_roles

概要

モデルに対して役割を紐づける
userモデルに付与すれば、それが管理者とか運用者とかになる
部長・課長とか付けて役職と紐づけても良いと思う

登録方法

$user->assignRole('operator', 'customer');

'operator'とかの箇所はrole_idでも可。
メソッドの中で、stringかnumericかチェックして検索条件を切り替えてる

解除方法

$user->removeRole('read');

permissions

概要

許可設定のマスタテーブル
予め必要なものを登録しておく

登録するものの例:

  • read
  • write
  • delete

など

登録方法

$permission = \Spatie\Permission\Models\Permission::create(['name' => 'read']);

model_has_permissions

概要

モデルに対して直接許可設定を付与する
userモデルに付与すれば、特権ユーザーみたいなものが作れる想定
(普通は管理者以上が触れる機能だけど、事務員さんに実際は入れてもらうので管理者じゃなくても権限付与したい、とかそういうヤツ)

登録方法

$user->givePermissionTo('read', 'write');

'read'とかの箇所はpermission_idでも可。
メソッドの中で、stringかnumericかチェックして検索条件を切り替えてる

解除方法

$user->revokePermissionTo('read');

role_has_permissions

概要

役割に対して許可設定を紐づけておくマスタテーブル

登録方法

以下のどちらか

$role->givePermissionTo($permission);
// or
$permission->assignRole($role);

まとめて登録したい場合は以下のどちらか使うとぐるぐるしなくて良い
(中でぐるぐるはしてるけど)

$role->syncPermissions($permissions);
// or
$permission->syncRoles($roles);

解除方法

役割に対する許可の設定を動的に変えるのがあまりイメージは湧かないけど以下でできる
(誤ったデータで作った場合に消したいとかそれくらいかな~と)

$role->revokePermissionTo($permission);
// or
$permission->removeRole($role);

2019/01/23補足

各ミドルウェアの実装上は使われていない。
どんなときに使われるかチェックしたら、

「hasPermissionViaRoleでPermissionを渡すと、そのPermissionがRoleに存在するかチェックする」

だった。
Roleごとに細かい権限付与したい場合は必要だけど、
カジュアルに役割 or 権限でチェックかけたい場合には、
このテーブルを使う必要はないですね。

最初に何が必要か

以下のテーブルについて、システムの初期セットアップで必要
(メンテナンス画面作ってちまちま入れても良いけど)

  • roles
  • permissions
  • role_has_permissions

マイグレーション実行する

テーブルのことが判ったところで、マイグレーション実行

php artisan migrate

この後はSeederとか使ってテキトーなデータを以下のテーブルに突っ込んでおく

  • roles
  • permissions
  • role_has_permissions

使い方

ユーザー登録

(めんどくさいので割愛)
User::createして戻り値で取ったuserをassignRoleかgivePermissionToする

コードに入れる

middleware

middlewareに設定したいのでmiddleware使う

以下を足す

App/Http/Kernel.php
protected $routeMiddleware = [
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];

上記の実装見れば判るけど、Laravelからすると特殊な構成の認証ユーザーの持ち方をしている場合は、
自前のクラスを作って差し替えれば、思い通りになる。
(実装自体は簡単過ぎるので書かない)

route.php

// rolesのデータでだけチェック
Route::group(['middleware' => ['role:admin|operator']], function () {
    //
});

// permissionsのデータでだけチェック
Route::group(['middleware' => ['permission:read|write']], function () {
    //
});

// roles or permissionsのデータに居るかをチェック
Route::group(['middleware' => ['role_or_permission:operator|read']], function () {
    //
});

role_has_permissionってどこで使われるんだ??

blade

使わないけど残しておく

@role('operator')
@endrole

@hasallroles('writer|admin')
@else
@endhasallroles

permission周りは他のと同じで@canを使うらしい

おわりに

大体理解した気がする。
業務システムに必要なところも実装されてそうだし良さげ。

今回の要件に合致すれば使おうかな。

技術的な課題としてはVueでどうやって連携させるかかなー。
メニュー周りくらい&SPAで書いてるわけじゃないから、bladeに直接vueコンポーネント書いて回避するようにする気がする。

34
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?