前言:spatie/Laravel-permission可以快捷的創建一個權限和角色,併爲角色賦予權限,給用戶賦予角色,從而讓用戶繼承角色的權限。這種模式適用用權限不是太過複雜的場景,但是一般的後臺設計都涉及了權限分組類似這樣的:
一般設計是直接根據不同情況,創建不同的權限組,再把用戶分配到對應的權限組裏面去(一個用戶可以對應多個權限組),從而簡化對用戶的權限管理操作
一、預熱:關於spatie/Laravel-permission的基本操作
參考文檔
基本使用
<?php
/**
* Created by PhpStorm.
* User: zheng
* Date: 2019/6/21
* Time: 17:12
*/
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use App\User;
class UserController extends Controller
{
/**
* 創建角色
* 說明,對遷移文件進行了修改,增加了一個description字段用於角色的描述
*/
public function baseRole()
{
Role::create(['name'=>'admin','description'=>'管理員']);
echo 'ok';
}
/**
* 創建權限
*/
public function addPermissions()
{
$permission = Permission::create(['name' => 'template/list','description'=>'點貨模板列表']);
echo 'ok';
}
/**
* 給角色添加權限
*/
public function givePermission()
{
$role = Role::where('name','template')->first();
$bool = $role->syncPermissions(['template/list']);
echo $bool;
}
/**
* 賦予用戶角色和權限
* 說明:角色的權限是自動繼承的,可以通過賦予用戶角色讓用戶繼承角色的權限,這種權限叫做“繼承權限”,
* 可以通過getPermissionsViaRoles()方法獲取,也可以直接給用戶賦予權限,這種權限叫做“直接權限”,
* 可以通過getDirectPermissions()方法獲取;
* getAllPermissions方法可以獲取用戶的所有權限(繼承權限和直接權限)
*/
public function giveUserRole()
{
$user = User::first();
// $user->givePermissionTo('template/list'); //直接給用戶添加權限
$user->assignRole('product'); //給用戶分配角色(同時繼承該角色的權限)
// $user->getPermissionsViaRoles(); //從用戶角色繼承權限(獲取當前用戶角色的所以權限)
//賦予當前角色的權限給用戶(繼承權限變爲直接權限,當角色刪除時,這些權限依舊存在)
$user->givePermissionTo($user->getPermissionsViaRoles());
echo $user;
}
/**
* 獲取用戶的所有權限
*/
public function getUserPermissionsList()
{
$user = User::first();
$user->givePermissionTo('product/list');
echo $user->getAllPermissions();
}
}
二、思路轉換
將spatie/Laravel-permission中的角色表(roles)當做是權限分組表,首先是新增權限分組(spatie/Laravel-permission的創建角色),例如表單是這樣的:
然後爲這個權限分組(角色)編輯權限,例如點擊編輯權限跳轉的頁面是這樣的:
展示當前權限組(角色)的所有權限,可以刪除權限(移除角色的某個權限),也可以點擊右上角的加號彈窗增加權限(給角色增加某個權限),彈窗裏面一個可搜索的下拉框,裏面是所有的權限列表,當然之前還有一個頁面添加權限(role表的記錄),這個role表也建議多增加一個字段描述一下當前權限,並且建議權限名就爲接口的api,方便鑑權時直接通過api來鑑權(使用$user->hasPermissionTo(‘權限名’));
到這一步再沒有改變spatie/Laravel-permission庫任何東西的情況下就爲權限進行了分組操作,其實當前的權限分組就是spatie/Laravel-permission的爲角色賦予權限,以上的全部操作都是使用spatie/Laravel-permission提供的api進行。
最後一步就是給用戶綁定權限組了,相當於是spatie/Laravel-permission中的給用戶分配角色(權限組),從而讓用戶繼承這些權限組(角色)的權限(使用getPermissionsViaRoles())獲取權限
三、優缺點總結
優點:不改動spatie/Laravel-permission的前提下(遷移文件的數據表加了字段對api調用沒有影響),使用spatie/Laravel-permission的方法便捷的對權限進行分組,方便快速開發權限模塊;
缺點:使用這個思路和權限模塊中的用戶都只能是繼承權限,即只能通過不同的權限組獲取權限,不能使用直接權限(只能通過角色繼承,不能直接賦予用戶權限),這就使用戶分組時可能會分出幾個權限類似的組去到達同一個模塊的不同權限的操作,例如普通訂單組(只能查看)和訂單操作組(可以查看,統計,彙總,刪除)。
說明:使用這種思路去完成權限模塊,其實spatie/Laravel-permission中的model_has_permissions表就沒有任何作用了,並且強烈建議不要使用givePermissionTo直接給用戶權限,因爲這樣會打破權限組的限制作用,使這個權限模塊理解起來很混亂,如果繞過權限組直接給用戶分配權限,就使得當前用戶與這個分配的權限所對應的權限組們形成間接的聯繫,但這個用戶是不屬於這些權限組中的任何一個的。