Code Monkey home page Code Monkey logo

tp5-rbac's Introduction

tp5-rbac

本扩展包是tp5的rbac包,使用了部分tp5的特性实现了关系型数据库中特殊数据结构的处理。

安装方法

先安装composer如果不知道怎么安装使用composer请自行百度。 打开命令行工具切换到你的tp5项目根目录

composer require gmars/tp5-rbac

如果该方法报错请按照以下方式操作:

  1. 打开项目根目录下的composer.json
  2. 在require中添加"gmars/tp5-rbac": "dev-master"
  3. 运行composer update

添加后composer.json应该有这样的部分:

    "require": {
        "php": ">=5.4.0",
        "topthink/framework": "^5.0",
        "gmars/tp5-rbac": "dev-master"
    },

v2.0+版本使用说明

配置

请将此配置加在config/app.php的配置中

'rbac' => [
    'type' => 'jwt',    //验证方式 jwt(token方式)形式或者service(基于cookie)方式
    'db' => '',        //rbac要使用的数据库配置为空则为默认库(生成表的前缀依赖此配置)
    'salt_token' => 'asdfasfdafasf',    //token加密密钥
    'token_key' => 'Authorization'      //header中用于验证token的名称
]

使用说明

实例化rbac

$rbac = new Rbac();

管理操作

初始化rbac所需的表

//可传入参数$db为数据库配置项默认为空则为默认数据库(考虑到多库的情形)
$rbac->createTable();

该方法会生成rbac所需要的表,一般只执行一次,为了安全,执行后会加锁,下次要执行需要删除锁文件再执行。

创建权限分组

$rbac->savePermissionCategory([
    'name' => '用户管理组',
    'description' => '网站用户的管理',
    'status' => 1
]);

编辑和修改调用同一个方法编辑时请在参数中包含主键id的值

创建权限节点

$rbac->createPermission([
    'name' => '文章列表查询',
    'description' => '文章列表查询',
    'status' => 1,
    'type' => 1,
    'category_id' => 1,
    'path' => 'article/content/list',
]);
  • 如果为修改则在传入参数数组中加入主键id的键值
  • type为权限类型1为后端权限2为前端权限主要考虑到spa使用
  • category_id为上一步创建的权限分组的id
  • 创建成功返回添加的该条权限数据,错误抛出异常

创建角色&给角色分配权限

$rbac->createRole([
    'name' => '内容管理员',
    'description' => '负责网站内容管理',
    'status' => 1
], '1,2,3');
  • 如果修改请在第一个参数中传入主键的键值
  • 第二个参数为权限节点的id拼接的字符串请使用英文逗号

给用户分配角色

$rbac->assignUserRole(1, [1]);
  • 该方法会删除用户之前被分配的角色
  • 第一个参数为用户id
  • 第二个参数为角色id的数组

获取权限分组列表

$rbac->getPermissionCategory([['status', '=', 1]]);
  • 参数支持传入id查询单条数据和标准的where表达式查询列表传为空数组则查询所有

获取权限列表

$rbac->getPermission([['status', '=', 1]]);
  • 参数支持传入id查询单条数据和标准的where表达式查询列表传为空数组则查询所有

获取角色列表

$rbac->getRole([], true);
  • 第一个参数支持传入id查询单条数据和标准的where表达式查询列表传为空数组则查询所有
  • 第二个参数选择是否查询角色分配的所有权限id默认为true

删除权限分组

$rbac->delPermissionCategory([1,2,3,4]);
  • 参数支持传入单个id或者id列表

删除权限

$rbac->delPermission([1,2,3,4]);
  • 参数支持传入单个id或者id列表

删除角色

$rbac->delRole([1,2,3,4]);
  • 参数支持传入单个id或者id列表
  • 删除角色会删除给角色分配的权限[关联关系]

验证操作

service方式

service方式因为要用到session一般要依赖于cookie。在用户登录后要获取用户权限操作

$rbac->cachePermission(1);
  • 传入参数为登录用户的user_id
  • 该方法会返回该用户所有的权限列表

用户请求时进行验证

$rbac->can('article/channel/list');
  • 如果有权限返回true如果没有权限返回false

jwt方式

jwt方式在前后端分离结构用的比较普遍。在用户登录后需要获取token

$rbac->generateToken(1);
  • 第一个参数为登录的用户id
  • 第二个参数为token有效期默认为7200秒
  • 第三个参数为token前缀 返回结果为
array(3) {
  ["token"] => string(32) "4c56b80f06d3d8810b97db33a1291694"
  ["refresh_token"] => string(32) "17914241bde6bfc46b20e643b2c58279"
  ["expire"] => int(7200)
}

使用refresh_token刷新权限

$rbac->refreshToken('17914241bde6bfc46b20e643b2c58279');

请在有效期内使用refresh_token来刷新授权 用户请求时验证

$rbac->can('article/channel/list');

< v2.0使用说明

数据迁移(可选,可以直接使用包中的gmars_rbac.sql文件导入)

在使用本插件之前需要有rbac锁需要的数据库。在迁移之前如果你的数据库中已有user数据表那么请你备份自己的user数据表后删除。

在你的项目的某个config.php中加入如下配置:

'migration' => [
    'path' => ROOT_PATH .'vendor/gmars/tp5-rbac/'
],

然后把命令行切换到你的项目根目录Windows是cmd运行如下命令

php think migrate:run

如果迁移运行成功会在你的数据库中生成如下几张表:

user              用户表
user_role         用户角色对应表
role              角色表
role_permission   角色权限对应表
permission        角色表

使用该插件--RBAC的管理

在一个系统中RBAC是基于角色的权限控制。作为开发人员需要明白这是两个不同的过程。第一个就是构建系统的RBAC结构,包括添加权限,角色,用户,用户角色对应关系,角色权限对应关系等。

在此先说明RBAC管理:

1.添加用户

这一步是在用户注册时要做的一步,就是讲注册的用户添加到user表中。

$rbacObj = new Rbac();
$data = ['user_name' => 'zhangsan', 'status' => 1, 'password' => md5('zhangsan')];
$rbacObj->createUser($data);

创建用户时传入唯一一个参数必须是数组。数组中应该包含用户表需要的数据。如果出现其他非user表的字段则会抛出异常。 该方法返回的结果为false或者Exception或者新添加用户的id

2.添加权限

这一步是构建系统的权限。一般我们是以请求的路由为权限的识别标志。在该插件中使用path字段。

例如我们的系统中有商品列表这样的一个操作需要授权。

其路由为 /index/goods/list

添加路由如下:

$rbacObj = new Rbac();
$data = [
    'name' => '商品列表',
    'status' => 1,
    'description' => '查看商品的所有列表',
    'path' => '/index/goods/list',
    'create_time' => time()
];
$rbacObj->createPermission($data);

3.添加角色

在RBAC的角色中角色是有父子关系的,也就是说所添加的角色可以是另一个角色的子角色。

$rbacObj = new Rbac();
$data = [
    'name' => '商品管理员',
    'status' => 1,
    'description' => '商品管理员负责商品的查看修改删除等操作',
    'sort_num' => 10,
    'parent_id' => 1
];
$rbacObj->createRole($data);

需要注意的是在data中有个字段为parent_id这个字段标识了所要添加的角色的父角色。如果留为空则便是添加的父角色。

4.为用户分配角色

当然一个用户可以有多个角色。一般是使用多选框或其他形式选择后以数组的方式传入的。

例如:

$rbacObj = new Rbac();
$rbacObj->assignUserRole(1, [1, 2]);

assignUserRole($userId, array $roleArray = [])

该方法的第一个参数为用户id第二个参数是一个一位数组,其元素为角色的id

5.为角色分配权限

例如:

$rbacObj = new Rbac();
$rbacObj->assignRolePermission(1, [1, 2]);

将id分别为1,2的权限分配给id为1的角色

6.删除角色

删除角色的同时必须删除角色和权限的对应数据

$rbacObj = new Rbac();
$rbacObj->delRole(1);

其中需要传入的是角色id

7.将一个角色移到另一个角色下

以上已经说明了角色是有父子关系的那么肯定能够移动其位置

$rbacObj = new Rbac();
$rbacObj->moveRole(1,3);

该例子是将id为1的角色移动到id为3的角色下作为子角色。

还有其他修改删除等方法的文档日后再补全,功能是有的

使用该插件--RBAC权限验证

登录后获取权限列表

如果自己写权限验证则请忽略这一步,如果要使用rbac插件来验证权限则必须要这样做。

在登录成功后做如下操作:

$rbacObj = new Rbac();
$rbacObj->cachePermission(1);

这个方法是查询id为1的用户的所有权限并且以path索引后存入cache

请求时的权限验证

当然对于每一个方法都要进行权限验证时我们一般是在某一个父类中定义一个方法进行权限验证,验证如下:

$rbacObj = new Rbac();
$rbacObj->can('/index/goods/list');

该方法是验证当前用户有没有操作/index/goods/list的权限,如果有则返回true如果无则返回false

其中can的参数可以使用tp5的特性获取。

tp5-rbac's People

Contributors

gmars avatar zjkal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

tp5-rbac's Issues

如果表有前缀,会导致很多错误,此项目还在维护么

class NestedSets 下
private $prefix; //表前缀
public function __construct{...
$this->prefix =Env::get('database.prefix','');
//如果是表名则处理配置
if (is_string($dbTarg)) {
$this->tableName = $this->prefix.$dbTarg;
}
如此处理,可以把表前缀加上,但是还是会报错。

variable type error: boolean

是不是意思是返回类型不能为 布尔值?

修改:
public function insert($parentId, array $data = [], $position = "top")
下 的返回:
return true; 改为 return 1;
可以正常。
请问此项目还在维护么?

rbac模块和nestedSets模块设置使用的表名有bug

在rbac模块中使用tp的 Db::name() 方法,到nestedSets模块中却使用了Db::table方法,问题就是,使用name方法会自动读取配置中的表前缀,而nestedSets中却又使用无前缀表名。这就导致了两个包依赖使用的表名始终无法统一。

使用JWT方式无法简便的获取用户ID

使用JWT方式无法简便的获取用户ID
采用前后端分离架构,后端无法使用session获取用户的登录状态
使用tp5-rbac的jwt方式时,能进行权限验证,但无法简便的获取用户的user_id
以下是我获取已登录用户user_id的方式

class Index extends Controller {
    protected $rbac;
    protected $user_id;
    public function initialize() {
        $this->rbac      = new Rbac();
        $controller_name = strtolower(request()->controller());
        $model_name      = strtolower(request()->action());
        $url             = $controller_name . '/' . $model_name;
        // 白名单,不需要进行验证的路径列表
        $white_list = [
            'index/getlogin',
            'index/getrbac',
            'index/index',
        ];
        if (!in_array($url, $white_list)) {
            try {
                // 验证权限
                $res = $this->rbac->can($url);
                // 获取用户ID
                $config_rbac     = config('rbac');
                $token_key       = $config_rbac['token_key'];
                $token           = request()->header($token_key);
                $permission_list = cache($token);
                $this->user_id   = $permission_list[$url]['user_id'];
            } catch (\Throwable $th) {
                json(['errno' => 2, 'msg' => $th->getMessage()])->send();exit;
            }
            if (false === $res) {
                json(['errno' => 2, 'msg' => '无权限访问'])->send();exit;
            }
        }

    }
}

关于 Class 'think\facade\Env' not found

你好,我使用
createTable
初始化数据库表,提示报错:

Class 'think\facade\Env' not found
我使用的是 thinkphp5.024
这个是类库是不是仅支持 5.1呀?我是需要升级5.1才能解决这个问题嘛?

新版本2.0数据迁移有问题

Syntax error or access violation: 1072 Key column 'left_key' doesn't exist in table
错误如上, 查看迁移内容:1、中存在表面带##号问题, 2、Syntax error or access violation: 1072 Key column 'left_key' doesn't exist in table
外键错误, 您可以测试一下,删除表, 重新request 一个TP5 然后安装。此问题就会出现。望能解决,十分感谢。最后,是一个建议。某些系统权限可能需要一个管理员权限。 再验证token的时候generateToken()方法中是否能再foreach之后添加一个特殊权限,用于验证超级管理员(后门管理员)

can方法的问题

can方法使用的是读取SESSION的方式 , 但是使用JWT 是无法验证权限的。 希望大佬能改一下can方法,能输入访问路径,已经读取用户名需要传入的方式。 这样就绕过了必须读取session 的方式。 在线等 急!

登录时,查询用户的权限存入缓存

在用户登录的时候查询出用户的权限,存入缓存,以便后面的访问做权限验证的时候,不用反复查库。但是,在存入缓存的时候,使用了一个写死的缓存名,也就是permission。当用户A登录后查询拥有 权限1。紧接着管理员登录,查询到权限123456789 就会覆盖掉前面的缓存。使用户A也拥有了管理员的权限
建议:
-可以把cache 替换为session
-根据用户id,生成一个动态的缓存名

因为使用cache来存储用户权限数据的不会存在获取不到的情况。检查下两个浏览器对cookie的支持。可以看看在获取权限前userid是否能取到。

因为使用cache来存储用户权限数据的不会存在获取不到的情况。检查下两个浏览器对cookie的支持。可以看看在获取权限前userid是否能取到。

Originally posted by @gmars in #12 (comment)

不好意思 应该是找不到这个$this->_permissionCachePrefix . $userId

在112 行中,还是用到了Session
Permission.php
112 Session::set('gmars_rbac_permission_name', $this->_permissionCachePrefix . $userId);

can检查的时候这里找不到
Rbac.php
358 $cacheName = Session::get('gmars_rbac_permission_name');

composer update也无法安装, 可能是因为我的TP5是5.1版本的吗

下面是错误信息
composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for gmars/tp5-rbac dev-master -> satisfiable by gmars/tp5-rbac[dev-master].
- gmars/tp5-rbac dev-master requires gmars/tp5-nestedsets dev-master -> satisfiable by gmars/tp5-nestedsets[dev-master] but these conflict with your requirements or minimum-stability.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.