这一篇主要讲述在
ThinkPHP框架中如何给
应用添加权限认证的功能。
ThinkPHP内置了RBAC(基于角色的权限认证)插件,可以很方便地给完成应用的权限认证功能。
ThinkPHP权限认证的设计原理
基于RBAC插件的权限认证需要用到三个关键数据表,通常验证工作会结合你需要验证的数据表(例如User表),RBAC组件默认会使用user表来进行验证,但是并不限制验证数据表,你一样可以使用RBAC组件来认证其他数据表。
ThinkPHP的权限授权和认证都是基于权限节点(也称之为管理节点),节点数据表的数据结构如下:
- CREATE TABLE `think_node` (
- `
id` smallint(6) unsigned NOT NULL auto_increment,- `
name` varchar(20) NOT NULL,- `
title` varchar(50) default NULL,- `
status` tinyint(1) unsigned default NULL,- `
remark` varchar(255) default NULL,- `
seqNo` smallint(6) unsigned default NULL,- `
parentId` smallint(6) unsigned NOT NULL,- `
level` tinyint(1) unsigned NOT NULL,- `
type` tinyint(1) NOT NULL default '0',-
PRIMARY KEY (`id`)- )
ENGINE=InnoDB DEFAULT CHARSET=utf8
ThinkPHP权限节点分为三层,由level字段表示,第一层属于
项目节点,第二层属于模块节点,第三层属于操作节点,所以目前的ThinkPHP框架的权限控制可以控制到操作节点层次。
应该说节点数据表仅仅是记录了管理节点信息,没有任何涉及到权限相关的数据,而权限的分配是由权限组来实现的。
权限组的数据结构如下:
- CREATE TABLE `think_group` (
- `
id` smallint(6) unsigned NOT NULL auto_increment,- `
name` varchar(20) NOT NULL,- `
parentId` smallint(6) default NULL,- `
status` tinyint(1) unsigned default NULL,- `
remark` varchar(255) default NULL,- `
ename` varchar(5) default NULL,-
PRIMARY KEY (`id`)- )
ENGINE=InnoDB DEFAULT CHARSET=utf8
而组-用户关联表则记录了每个用户所属的权限组
- CREATE TABLE `think_groupuser` (
- `
groupId` mediumint(9) unsigned default NULL,- `
userId` mediumint(9) unsigned default NULL,-
KEY `groupId` (`groupId`),-
KEY `userId` (`userId`)- )
ENGINE=InnoDB DEFAULT CHARSET=utf8;
最关键的数据表就是权限控制数据表了,由access表来保存所有权限节点和组的关联信息,这里记录了每个权限组所具有的权限节点信息。
- CREATE TABLE `think_access` (
- `
groupId` smallint(6) unsigned NOT NULL,- `
nodeId` smallint(6) unsigned NOT NULL,- `
level` tinyint(1) NOT NULL,- `
parentNodeId` smallint(6) NOT NULL) ENGINE=MyISAM;
数据表中的level和parentNodeId其实不是必须的,只是为了更快的获取权限数据。
因此,
框架的权限认证原理就是根据当前登录用户的编号获取所在权限组的授权节点信息,如果找到匹配数据就表示有当前操作权限,反之则表示没有相关权限。
其过程为:
判断用户是否登录->判断用户所在组->取得所在组的并集授权节点
在RBAC插件里面
定义了如何获取和认证节点的一种方法。具体的认证方式说明和使用,请参考ThinkPHP安全体系-委托认证和决策访问这篇文章。
ThinkPHP旧版的Admin管理项目示例里面包含了如何在后台进行节点添加和进行授权的操作和实现方式。在项目应用中,还可以根据实际项目的需要,把节点管理和授权机制融合到你的
系统管理中。