1. Laravel のインストール
2. authのインストールとDBマイグレーション
//Laravel6では変更になりましたね。
$ php artisan make:auth
login Register のボタンを右上に確認。
2-1. laravel-permission を composerからインストール
Laravel5.7以下 -> v2
Laravel5.8以上 -> v3
//今回はLaravel5.5なのでv2をインストール
$ composer require spatie/laravel-permission:2.*
2-2. app/Http/Kernel.php に追記
60行目前後
protected $routeMiddleware = [
....
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
]
....
2-3. app/User.php (app/Models/User.php) に追記
....
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
....
use HasRoles;
]
}
3. DBテーブルのマイグレーション
artisanコマンドで マイグレーションファイルを生成します
$ php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
2つのファイルが作成されます。
./database/migrations/2018_07_31_072708_create_permission_tables.php
./bootstrap/cache/services.php
4. コンフィグファイルのマイグレーション
$ php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
次の1ファイルが作成されます
./config/permission.php
5. DBテーブルの作成
$ php artisan migrate
5つのDBテーブルが作成されます。
model_has_permissions
model_has_roles
permissions
roles
role_has_permissions
6.DBデータの作成
6-1. PermissionTableSeeder.php
シーダー雛形作成
$ php artisan make:seeder PermissionTableSeeder
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;//追加
class PermissionTableSeeder extends Seeder
{
public function run()
{
//追加
$permissions = [
'admin_permission',
'manager_permission',
'staff_permission',
'customer_permission',
];
foreach ($permissions as $permission) {
Permission::create(['name' => $permission]);
}
}
}
シーダーの実行
$ php artisan db:seed --class=PermissionTableSeeder
6-2. RoleTableSeeder.php 準備
シーダー雛形作成
$ php artisan make:seeder RoleTableSeeder
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;//追加
class RoleTableSeeder extends Seeder
{
public function run()
{
//追加
$roles = [
'admin',
'manager',
'staff',
'customer',
];
foreach ($roles as $role) {
Role::create(['name' => $role]);
}
}
}
シーダーの実行
$ php artisan db:seed --class=RoleTableSeeder
6-3. RoleHasPermissionTableSeeder.php 準備
シーダー雛形作成
$ php artisan make:seeder RoleHasPermissionTableSeeder
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;//追加
use Spatie\Permission\Models\Role;//追加
class RoleHasPermissionTableSeeder extends Seeder
{
public function run()
{
//追加
// admin
$permissions = [
'admin_permission',
'manager_permission',
'staff_permission',
];
$role = Role::findByName('admin');
$role->givePermissionTo($permissions);
// manager
$permissions = [
'manager_permission',
'staff_permission',
];
$role = Role::findByName('manager');
$role->givePermissionTo($permissions);
// staff
$permissions = [
'staff_permission',
];
$role = Role::findByName('staff');
$role->givePermissionTo($permissions);
// customer
$permissions = [
'customer_permission',
];
$role = Role::findByName('customer');
$role->givePermissionTo($permissions);
}
}
シーダーの実行
$ php artisan db:seed --class=RoleHasPermissionTableSeeder
4. UserTableSeeder.php 準備
シーダー雛形作成
$ php artisan make:seeder UserTableSeeder
<?php
use App\User;
use Illuminate\Database\Seeder;
class UserTableSeeder extends Seeder
{
public function run()
{
//追加
// admin
$user = User::create([
'name' => 'web管理責任者',
'email' => 'admin@gmail.com',
'password' => Hash::make('admin'),
]);
$user->assignRole('admin');
// manager
$user = User::create([
'name' => 'サイトマネージャ',
'email' => 'manager@gmail.com',
'password' => Hash::make('manager'),
]);
$user->assignRole('manager');
// staff
$user = User::create([
'name' => 'スタッフ',
'email' => 'staff@gmail.com',
'password' => Hash::make('staff'),
]);
$user->assignRole('staff');
// customer
$user = User::create([
'name' => 'カスタマー',
'email' => 'customer@gmail.com',
'password' => Hash::make('customer'),
]);
$user->assignRole('customer');
}
}
シーダーの実行
$ php artisan db:seed --class=UserTableSeeder
5. シーダーのやり直し
$ php artisan migrate:rollback --step=1
メソッド一覧
Permission
public static create(array $attributes = [])
public roles(): BelongsToMany
public users(): MorphToMany
public static findByName(string $name, $guardName = null): PermissionContract
public static findById(int $id, $guardName = null): PermissionContract
public static findOrCreate(string $name, $guardName = null): PermissionContract
protected static getPermissions(): Collection
Role
public static create(array $attributes = [])
public permissions(): BelongsToMany
public users(): MorphToMany
public static findByName(string $name, $guardName = null): RoleContract
public static findById(int $id, $guardName = null): RoleContract
public static findOrCreate(string $name, $guardName = null): RoleContract
public hasPermissionTo($permission): bool
Userモデルなど既存のモデルに追加される拡張メソッド
use HasRoles で拡張されるメソッド
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
..........
//auth()->user()->{method}
public static bootHasRoles()
public roles(): MorphToMany
public scopeRole(Builder $query, $roles): Builder
public assignRole(...$roles)
public removeRole($role)
public syncRoles(...$roles)
public hasRole($roles): bool
public hasAnyRole($roles): bool
public hasAllRoles($roles): bool
public getDirectPermissions(): Collection
public getRoleNames(): Collection
protected getStoredRole($role): Role
protected convertPipeToArray(string $pipeString)
・Controllerでの例
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
---
public function index() {
//ログインユーザーの role を取得
echo auth()->user()->getRoleNames(); //["customer"]
}
}
use HasPermissions で拡張されるメソッド
use Spatie\Permission\Traits\HasPermissions;
class User extends Authenticatable
{
use HasPermissions;
..........
public static bootHasPermissions()
static::deleting( ($model) {
public permissions(): MorphToMany
public scopePermission(Builder $query, $permissions): Builder
protected convertToPermissionModels($permissions): array
public hasPermissionTo($permission, $guardName = null): bool
public hasAnyPermission(...$permissions): bool
public hasAllPermissions(...$permissions): bool
protected hasPermissionViaRole(Permission $permission): bool
public hasDirectPermission($permission): bool
public getPermissionsViaRoles(): Collection
public getAllPermissions(): Collection
public givePermissionTo(...$permissions)
public syncPermissions(...$permissions)
public revokePermissionTo($permission)
protected getStoredPermission($permissions)
protected ensureModelSharesGuard($roleOrPermission)
protected getGuardNames(): Collection
protected getDefaultGuardName(): string
public forgetCachedPermissions()
● Bladeビューでの権限(Permission)判定
Permission を判別。
<p>
@can('admin_permission')
admin_permission を持っています <br>
@endcan
@can('manager_permission')
manager_permission を持っています <br>
@endcan
@can('staff_permission')
staff_permission を持っています <br>
@endcan
</p>
● Bladeビューでのロール(Role)判定
Role を判別。
<p>
@hasrole('manager')
managerの役割をもっています。
@else
managerの役割を持っていません。
@endhasrole
@role('staff')
あなたはstaffの役割を持っています。
@elserole('customer')
あなたはcustomerの役割を持っています。
@else
役割を持っていません。
@endrole
</p>
● Routes での権限、ロール判定
63行目前後
protected $routeMiddleware = [
// ...
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];
Routes 設定
// 誰でもアクセス可能
Route::resource('users', 'UserController');
// 「ログイン」している時のみアクセス可能
Route::group(['middleware' => ['auth']], function() {
Route::resource('users', 'UserController');
});
// 「ログイン」かつ「admin_permissionを持つ」時のみアクセス可能
Route::group(['middleware' => ['auth', 'permission:admin_permission']], function() {
Route::resource('users', 'UserController');
});
LGTMお願いします!
モチベーションがあがります!