lumen-Permission 權限管理使用心得


安裝

composer require spatie/laravel-permission

  github上有詳細介紹:https://github.com/spatie/laravel-permission

 

我先來說一下核心的判斷是否授權,

$user = AdminUser::find($adminId);
$user->hasPermissionTo($name, 'admin')

$user為默認的User的Model對應find后實例,$name為當前的路由,可以用以下3種方式獲取

$router->currentRouteName();
$request->path();
$request->route()[1]['uri'];

前兩種比較常見,第三種是獲取當前訪問路由的$name值,像/xxx/{id}之類的,感覺比較實用,具體可以看下 http://www.cnblogs.com/cxscode/p/8435405.html

 

接下來講講Permission自動生成的5張表,roles角色表, role_has_permissions角色關聯權限表, permissions權限表, model_has_roles用戶關聯角色表, model_has_permission用戶關聯權限表

 

roles表

比較重要兩個字段name和guard_name,name是角色名,guard_name是應該算是權限的域,和中間件有關系,其層高於整個rbac(權限),這個值一般是admin,可能這個管理員還有前台的權限,那可能這部分權限的guard_name就會是web之類的詞了,

 

permissions表

比較重要兩個字段name和guard_name,name存的是當前權限訪問的路由,當然也可以是其他,一般是用路由,guard_name同roles表

 

model_has_roles表 和 model_has_permission表

這兩個表的model_id就是對應用戶表的id了

 

以下摘自Laravel-Permission 使用心得:http://blog.csdn.net/complicated19921001/article/details/78317969

1.執行完github上的命令,你的數據庫有 
roles role_has_permissions permissions model_has_roles model_has_permission

2.在你的項目里 你不需要為role permission建立model,,你只需要userModel

3.在userModel里加上

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class UserModel extends Authenticatable
{
    use HasRoles;
    protected $guard_name = 'web';
    //your code
}

  

new一個UserModel對象,這些方法都可以使用了, 
1. user>assignRole(writer);

2.user->removeRole(‘writer’);

3. user>syncRoles(params);user

4.role->givePermissionTo(‘edit articles’); 

5. role>revokePermissionTo(editarticles);6.role->syncPermissions(params);

 

個人使用心得

PS:強烈建議在 UserModel 里面添加上 guard_name 字段,並賦予值。在創建新role時候,也手動指定 guard_name的值,原因有二: 
1.這個值會一並插入到表里 guard_name 字段,該字段默認不能為null 
2.這個是區分role的字段, 
eg: post-manager web; 
post-manager admin; 
這兩個roleName一樣,但是guard_name不一樣,這也是兩個角色; 
說的通俗一點,guard_name這個值有點“分組”的概念。

在創建新role的時候,guard_name如果沒有,那就取auth.defaults.guard的值,這個laravel默認是“web”,這是源碼

public static function create(array $attributes = [])
    {
        $attributes['guard_name'] = $attributes['guard_name'] ?? config('auth.defaults.guard');

        if (static::where('name', $attributes['name'])->where('guard_name', $attributes['guard_name'])->first()) {
            throw RoleAlreadyExists::create($attributes['name'], $attributes['guard_name']);
        }

        if (app()::VERSION < '5.4') {
            return parent::create($attributes);
        }

        return static::query()->create($attributes);
    }

  

使用 assignRole() syncRoles(); getRoleNames()這些方法的時候,回去根據$guard_name值去判斷角色是否存在,如果你沒有在UserModel里面指明,它會去取config\auth.php的 guards的值,這是源碼

protected function getGuardNames(): Collection
    {
        if ($this->guard_name) {
            return collect($this->guard_name);
        }

        return collect(config('auth.guards'))
            ->map(function ($guard) {
                return config("auth.providers.{$guard['provider']}.model");
            })
            ->filter(function ($model) {
                return get_class($this) === $model;
            })
            ->keys();
    }

  

可以看出 如果你的類里定義了 guard_name 那就直接取出,否則去取config\auth.php 的 guards里的一個model對應的key值作為guard_name,根據這個值去判斷角色的存不存在。

我在使用的時候就遇到一個問題,數據里角色明明有,但是一執行assignRole(‘post-manager’)就報 “找不到角色”的錯誤。后來看了源碼才知道是這樣: 
我的guards是自己添加,我自己在config\auth.php里的guards數組里添加 

‘admin’=>[ 
‘driver’ => ‘session’, 
‘provider’ => ‘admins’, 
], 

  

也就是說在assignRole() getRoleNames()的時候,guard_name的值是 ‘admin’

這就是問題的所在,創建的時候默認的是web(auth.defaults.guard),但是查詢role的時候是admin(guards里的一個model對應的key值),所以會說“找不到角色這個問題” 
所以,再次強調一下,

1.創建新role的時候,guard_name手動添加到數組里面 
2.在UserModel里定義了protected= $guard_name,並賦予和上一步一樣的值(這樣它就不會再去config\auth.php里的guards數組去取值了,就不會出現guard_name不一致的情況)

 

我個人比較喜歡的是 user->role->permission的方式,user只擁有role,而role只擁有permission 這樣user的權限完全取決於它的角色,user不會直接跟permission打交道 
而Laravel-Permission 是可以直接給user賦予permission(model_has_permissions表就是干這個的)。如果按我比較喜歡的風格,這個表就用不到了 。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM