zoukankan      html  css  js  c++  java
  • 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 IlluminateFoundationAuthUser as Authenticatable;
    use SpatiePermissionTraitsHasRoles;
    
    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里面指明,它会去取configauth.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 那就直接取出,否则去取configauth.php 的 guards里的一个model对应的key值作为guard_name,根据这个值去判断角色的存不存在。

    我在使用的时候就遇到一个问题,数据里角色明明有,但是一执行assignRole(‘post-manager’)就报 “找不到角色”的错误。后来看了源码才知道是这样: 
    我的guards是自己添加,我自己在configauth.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,并赋予和上一步一样的值(这样它就不会再去configauth.php里的guards数组去取值了,就不会出现guard_name不一致的情况)

    我个人比较喜欢的是 user->role->permission的方式,user只拥有role,而role只拥有permission 这样user的权限完全取决于它的角色,user不会直接跟permission打交道 
    而Laravel-Permission 是可以直接给user赋予permission(model_has_permissions表就是干这个的)。如果按我比较喜欢的风格,这个表就用不到了 。

  • 相关阅读:
    1001.A+B for Matrices
    1016.火星A+B
    1468.Sharing
    1464.Hello World For U
    约瑟夫问题pascal程序
    约数研究pascal程序
    迷宫pascal程序
    魔法照片pascal程序
    均分纸牌pascal程序
    多项式输出pascal程序
  • 原文地址:https://www.cnblogs.com/cxscode/p/8444473.html
Copyright © 2011-2022 走看看