RBAC权限控制


本文章是自己在学习php的时候,使用thinkPHP开发一个简单的OA系统,对RBAC权限管理的一个总结。
 
1. 权限管理(RBAC)
RBAC(role  base  access  control ): 基于角色的用户访问权限控制
 
2.传统方式的权限设置和基于角色权限控制的区别
1)传统方式的权限设置
实现方式:具体的操作权限与用户直接对应,如下所示:

 

该方式权限设置特点:
管理员需要为新增、离职的用户进行具体权限分配,操作的时候 效率低下、 权限设置没有统一标准较凌乱,不适合大项目使用。

 

2)基于角色的权限分配

 

该方式权限设置特点:

用户----->(角色)------>权限

用户和组(角色)对应,组和权限对应

管理员进行权限设置只需要考虑用户是哪个组的即可,操作非常容易、高效、简便,

组别拥有的权限通过前期准备工作已经做好,权限设置非常标准化。

是一种非常科学的权限设置方式。

 
3. RBAC的原理
 
 
RBAC权限管理的表设计:
 

 

以下是oa系统权限管理的表设计
权限表--创建节点表---(体现能够操作的控制器和方法)(加粗的一般是必须字段,node_module不一定必须,如果是在同一个模块,就可以不用加module这个字段)
CREATE TABLE tp_node(
  node_id INT(6) AUTO_INCREMENT PRIMARY KEY, #节点id
  node_name VARCHAR(20) UNIQUE NOT NULL, #节点名称
  node_title VARCHAR(50) NOT NULL,   #存放class name
  node_pid SMALLINT(6) UNSIGNED NOT NULL, #父节点id
  node_module VARCHAR(20) NOT NULL DEFAULT 'null', #模块名
  node_controller VARCHAR(20) NOT NULL DEFAULT 'null', #控制器
  node_action VARCHAR(20) NOT NULL DEFAULT 'null', #方法
  node_path VARCHAR(255) NOT NULL,    #module-controller-action(例:admin-index-index)
  node_level TINYINT(1) UNSIGNED NOT NULL, #用于区分菜单层级
  node_sort TINYINT UNSIGNED NOT NULL, #用于排序
  node_show TINYINT DEFAULT 1     #表明当前节点是否会显示在左侧的管理菜单中
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
 
--节点添加
INSERT INTO tp_node VALUES (1,'日常办公','office',0,'Admin','Main','home','Admin-Main-home',0,1,1);
 
--Dept控制器
INSERT INTO tp_node VALUES (2,'组织结构','agency',0,'','','','null',0,2,1);
 
INSERT INTO tp_node VALUES (3,'部门列表','',2,'Admin','Dept','index','Admin-Dept-index',1,21,1);
INSERT INTO tp_node VALUES (4,'添加部门','',2,'Admin','Dept','add','Admin-Dept-add',1,22,1);
INSERT INTO tp_node VALUES (5,'添加部门操作','',2,'Admin','Dept','addOk','Admin-Dept-addOk',1,23,0);
INSERT INTO tp_node VALUES (6,'删除部门','',2,'Admin','Dept','del','Admin-Dept-del',1,24,0);
INSERT INTO tp_node VALUES (7,'编辑部门','',2,'Admin','Dept','edit','Admin-Dept-edit',1,25,0);
INSERT INTO tp_node VALUES (8,'修改部门','',2,'Admin','Dept','modify','Admin-Dept-modify',1,26,0);
INSERT INTO tp_node VALUES (9,'批量删除','',2,'Admin','Dept','dels','Admin-Dept-dels',1,27,0);
 
--User控制器
INSERT INTO tp_node VALUES (10,'职员管理','nav-info',0,'','','','null',0,10,1);
 
INSERT INTO tp_node VALUES (11,'职员列表','',10,'Admin','User','index','Admin-User-index',1,101,1);
INSERT INTO tp_node VALUES (12,'添加职员','',10,'Admin','User','add','Admin-User-add',1,102,1);
INSERT INTO tp_node VALUES (13,'添加职员操作','',10,'Admin','User','addOk','Admin-User-addOk',1,103,0);
INSERT INTO tp_node VALUES (14,'ajax表格','',10,'Admin','User','getContent','Admin-User-getContent',1,104,0);
INSERT INTO tp_node VALUES (15,'统计图','',10,'Admin','User','charts','Admin-User-charts',1,105,0);
INSERT INTO tp_node VALUES (16,'编辑职员','',10,'Admin','User','edit','Admin-User-edit',1,106,1);
INSERT INTO tp_node VALUES (17,'修改职员','',10,'Admin','User','modify','Admin-User-modify',1,107,0);
INSERT INTO tp_node VALUES (18,'删除职员','',10,'Admin','User','del','Admin-User-del',1,108,0);
 
INSERT INTO tp_node VALUES (19,'公文起草','gongwen',0,'','','','null',0,19,1);
INSERT INTO tp_node VALUES (20,'公文管理','index',19,'Admin','Doc','index','Admin-Doc-index',1,191,1);
INSERT INTO tp_node VALUES (21,'添加公文','add',19,'Admin','Doc','add','Admin-Doc-add',1,192,1);
 
INSERT INTO tp_node VALUES (22,'知识管理','knowledge',0,'','','','null',0,22,1);
INSERT INTO tp_node VALUES (23,'知识列表','index',22,'Admin','Knowledge','index','Admin-Knowledge-index',1,221,1);
INSERT INTO tp_node VALUES (24,'添加知识','add',22,'Admin','Hnowledge','add','Admin-Knowledge-add',1,222,1);
 
INSERT INTO tp_node VALUES (25,'邮件管理','email',0,'','','','null',0,25,1);
INSERT INTO tp_node VALUES (26,'收件箱','index',25,'Admin','Email','index','Admin-Email-index',1,251,1);
INSERT INTO tp_node VALUES (27,'写邮件','add',25,'Admin','Email','add','Admin-Email-add',1,252,1);
 
INSERT INTO tp_node VALUES (28,'系统管理','system',0,'','','','null',0,7,1);
INSERT INTO tp_node VALUES (29,'角色管理','role',28,'Admin','Role','index','Admin-Role-index',1,281,1);
INSERT INTO tp_node VALUES (30,'节点管理','node',28,'Admin','Node','index','Admin-Node-index',1,282,1);
 
 
 
--创建角色表--
CREATE TABLE tp_role( #加粗的是必须的字段
  role_id INT AUTO_INCREMENT PRIMARY KEY, #角色id
  role_name VARCHAR(20) UNIQUE NOT NULL, #角色名
  role_ids VARCHAR(255) NOT NULL,  #权限id列表
  role_path VARCHAR(255) NOT NULL #module-controller-action(例:admin-index-index)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
 
 
//user表(加粗的是必须字段,其他字段根据具体需求添加)
create table tp_user( 
  id int not null auto_increment primary key,
  username varchar(40) not null,
  roleid int not null default 0,  #角色id
  password char(32) not null,
  nickname varchar(40),
  deptid int not null,
  sex varchar(10) not null,
  birthday date not null,
  tel varchar(11) not null,
  email varchar(50) not null,
  addtime int
) engine=myisam default charset=utf8;
 
RBAC权限访问最终体现在两个地方
1)动态生成左侧管理菜单
2)防跳墙访问
 
动态生成左侧管理菜单
思路:
在用户登录时,在session中记录该用户的user_roleid字段。
根据roleid的值从role表取出改用户可以操作的所有权限的节点id(role_ids)
根据ids从node表中取出具体可以操作的权限
防跳墙访问
在TP当中定义了3个常量:MODULE_NAME(当前访问的模块名)、CONTROLLER_NAME(当前访问的控制器名)、ACTION_NAME(当前访问的方法名)   MODULE_NAME-CONTROLLER_NAME-ACTION_NAME
CommonController控制器, _initialize () 在实例化控制器时,自动调用(_initialize()是tp的controller类中,构造方法
 有一段代码if(method_exists($this,'_initialize'))
            $this->_initialize();
_initialize()方法在controller中,并没有定义,就是给后面继承该控制器的类使用的。这里的CommonController控制器就是通过这个原理实现的
  1. 在CommonController/_initialize()方法中,用模块名、控制器名、方法名组成一个字符串。
  2. 使用上步产生的字符串和role表当中的role_path进行比较,如果字符串存在于role_path字段中,则说明正常访问;反之,则为跳墙访问。
根据session中的roleid,从role表中获取role_path字段。 在登录时,就把role_path记录在session中。
在CommonController/_initialize()方法中,使用获取到的当前模块控制器方法的字符串和session中的rolepath进行比较。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM