thinkPHP5 使用Rabc实现权限管理 及其5.1安装方式补充

TP5 RBAC插件构建 rbac关系

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

使用gmars/tp5-rbac拓展来实现权限管理 gmars/tp5-rbac地址:https://packagist.org/packages/gmars/tp5-rbac

一:gmars/tp5-rbac安装

composer require gmars/tp5-rbac

二:gmars/tp5-rbac使用

1:Rbac数据库创建

在gmars/tp5-rbac中我们需要使用到六张表,分别为:权限节点表(permission),permission_category(权限分组表),role(角色表),role_permission(角色权限关联表),user(用户表),user_role(用户角色关联表)

当我们使用composer将gmars/tp5-rbac下载下来之后,我们可以发现在vendorgmarstp5-rbac目录下有一个gmars_rbac.sql文件,此文件内就为我们所需要创建表的sql

下面sql中###为你的表前缀,下面只是展示我们呢所需要的表sql,创建表gmars/tp5-rbac提供了方法来帮我们自动创建我们所需要的表

//实例化rbac
$rbac = new Rbac();
//初始化rbac所需的表,可传入参数$db为数据库配置项默认为空则为默认数据库(考虑到多库的情形)
$rbac->createTable();

上面的方法会生成rbac所需要的表,一般只执行一次,为了安全,执行后会加锁,下次要执行需要删除锁文件再执行 (1):权限节点表(permission)

DROP TABLE IF EXISTS `###permission`;
CREATE TABLE `###permission` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '权限节点名称',
  `type` smallint(4) unsigned NOT NULL DEFAULT '0' COMMENT '权限类型1api权限2前路由权限',
  `category_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '权限分组id',
  `path` varchar(100) NOT NULL DEFAULT '' COMMENT '权限路径',
  `path_id` varchar(100) NOT NULL DEFAULT '' COMMENT '路径唯一编码',
  `description` varchar(200) NOT NULL DEFAULT '' COMMENT '描述信息',
  `status` smallint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态0未启用1正常',
  `create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_permission` (`path_id`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限节点表';

(2):permission_category(权限分组表

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `###permission_category`;
CREATE TABLE `###permission_category` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '权限分组名称',
  `description` varchar(200) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '权限分组描述',
  `status` smallint(4) unsigned NOT NULL DEFAULT '1' COMMENT '权限分组状态1有效2无效',
  `create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '权限分组创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT '权限分组表';

(3):role(角色表) DROP TABLE IF EXISTS ###role; CREATE TABLE ###role ( id int(11) unsigned NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL DEFAULT '' COMMENT '角色名', description varchar(200) NOT NULL DEFAULT '' COMMENT '角色描述', status smallint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态1正常0未启用', sort_num int(11) unsigned NOT NULL DEFAULT '0' COMMENT '排序值', PRIMARY KEY (id), KEY idx_role (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';

(4):role_permission(角色权限关联表)

DROP TABLE IF EXISTS `###role_permission`;
CREATE TABLE `###role_permission` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `role_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '角色编号',
  `permission_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '权限编号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限对应表';

(5):user(用户表)

DROP TABLE IF EXISTS `###user`;
CREATE TABLE `###user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
  `password` varchar(64) NOT NULL DEFAULT '' COMMENT '用户密码',
  `mobile` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号码',
  `last_login_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最后一次登录时间',
  `status` smallint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态0禁用1正常',
  `create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '账号创建时间',
  `update_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '信息更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_user` (`user_name`,`mobile`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

(6):user_role(用户角色关联表)

DROP TABLE IF EXISTS `###user_role`;
CREATE TABLE `###user_role` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
  `role_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '角色id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色对应关系';

2:rbac的相关操作

(1)创建权限分组

//实例化rbac
$rbac = new Rbac();
//创建权限分组
$rbac->savePermissionCategory([
    'name' => '用户管理组',
    'description' => '网站用户的管理',
    'status' => 1
]);

当savePermissionCategory方法中包含了主键id时为编辑权限分组

(2)创建权限节点

//实例化rbac
$rbac = new Rbac();
//创建权限节点
$rbac->createPermission([
    'name' => '文章列表查询',
    'description' => '文章列表查询',
    'status' => 1,
    'type' => 1,//type为权限类型1为后端权限2为前端权限
    'category_id' => 1,//权限分组的id
    'path' => 'article/content/list',
]);

当createPermission方法中包含了主键id时为编辑权限节点

(3)创建角色&给角色分配权限 在RBAC的角色中角色是有父子关系的,也就是说所添加的角色可以是另一个角色的子角色。

//实例化rbac
$rbac = new Rbac();
//创建角色&并同时给角色分配权限
$rbac->createRole([
    'name' => '内容管理员',
    'description' => '负责网站内容管理',
    'status' => 1
], '1,2,3');

当createRole方法的第一个参数中包含了主键id时为编辑角色,第二个参数为权限节点的id拼接的字符串 需要注意的是在数组第一个参数可选字段为parent_id这个字段标识了所要添加的角色的父角色。如果留为空则便是添加的父角色。

//单独给角色分配权限
$rbacObj = new Rbac();
$rbacObj->assignRolePermission(1, [1, 2]);

(4)给用户分配角色

//实例化rbac
$rbac = new Rbac();
//给用户分配角色
$rbac->assignUserRole(1, [1]);

第一个参数为用户id,第二个参数为角色id的数组,此方法会先删除用户之前分配的角色,然后重新给用户分配角色

(5)获取权限分组列表

//实例化rbac
$rbac = new Rbac();
//获取权限分组列表
$rbac->getPermissionCategory([['status', '=', 1]]);//参数为权限分组表的条件

(6)获取权限列表

//实例化rbac
$rbac = new Rbac();
//获取权限列表
$rbac->getPermission([['status', '=', 1]]);//参数为权限表条件

(7)获取角色列表

//实例化rbac
$rbac = new Rbac();
//获取角色列表
$rbac->getRole([], true);

第一个参数为role表的条件,第二个参数为true时查询角色分配的所有权限id

(7.1补充)将一个角色移到另一个角色下 以上已经说明了角色是有父子关系的那么肯定能够移动其位置

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

(8)删除权限相关方法 删除角色的同时必须删除角色和权限的对应数据

删除权限分组
$rbac->delPermissionCategory([1,2,3,4]);
删除权限
$rbac->delPermission([1,2,3,4]);
删除角色
$rbac->delRole([1,2,3,4]);

(9)权限验证 登录后获取权限列表 如果自己写权限验证则请忽略这一步,如果要使用rbac插件来验证权限则必须要这样做。

[1]service方式 service方式因为要用到session一般要依赖于cookie,在用户登录后获取用户权限并将用户权限进行缓存

$rbac->cachePermission(1);//参数为登录用户的user_id,返回值为用户权限列表

验证,判断用户对于指定的节点是否具有权限:

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

[2]jwt方式 jwt方式在前后端分离结构用的比较普遍。在用户登录后需要获取token,将下面方法获取到的token传递到前端

$rbac->generateToken(1);//第一个参数为登录的用户id,第二个参数为token有效期默认为7200秒,第三个参数为token前缀 返回结果为

返回值示例如下:

array(3) {
  ["token"] => string(32) "4c56b80f06d3d8810b97db33a1291694"
  ["refresh_token"] => string(32) "17914241bde6bfc46b20e643b2c58279"
  ["expire"] => int(7200)
}

使用refresh_token刷新权限,有效期内使用refresh_token来刷新授权

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

验证,前端将token传递到后端,后端校验用户是否具有指定节点权限

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

该方法是验证当前用户有没有操作/index/goods/list的权限,如果有则返回true如果无则返回false 其中can的参数可以使用tp5的特性获取。

关于5.1的安装补充

需要依赖环境 先安装composer如果不知道怎么安装使用composer请自行百度。 打开命令行工具切换到你的tp5项目根目录 如果没有安装migaration与nestedset,先安装

composer require topthink/think-migration:*
composer require gmars/tp5-nestedsets:dev-master
composer require gmars/tp5-rbac

1 如果该方法报错请按照以下方式操作: 打开项目根目录下的composer.json 在require中添加”gmars/tp5-rbac”: “dev-master” 运行composer update

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

数据迁移

在使用本插件之前需要有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结构,包括添加权限,角色,用户,用户角色对应关系,角色权限对应关系等。 1.添加用户 这一步是在用户注册时要做的一步,就是讲注册的用户添加到user表中。


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

....... 详见 https://packagist.org/packages/gmars/tp5-rbac 数据迁移部分

记录你我
请先登录后发表评论
  • latest comments
  • 总共0条评论