tp教程:
1.查询当前用户有权访问的所有节点,(项目下的--模块--方法)组成。
2.检查用户是否登录(登录调用3,否则跳转)
3.将用户有权访问的所有节点以array形式保存到session(数组为三维数组array('项目'=>array('模块'=>array(方法=>'update'))))
3.检查用户是否有权限访问当前的模块--方法。(true则访问,false则不能访问)
用户登录成功--->检查当前操作的方法是否存在于用户有权访问的节数组中
4.检查当前的操作(模块--方法)是否需要认证 (一种是需要认证的。另一种是不需要认证。)
检查当前登录用户是否有操作当前模块--方法 _initialize()。
将initialize()方法放到action 基类的__constuct()方法中执行。
所有的控制器类都继承自action基类。
--------------------------------------------
每次只能调用action下的一个方法,才能保证权限调用的合理性。
调用第二次方法,__constuct()不在执行。
构造函数是类中的一个特殊函数,当使用 new 操作符创建一个类的实例时,构造函数将会自动调用。当函数与类同名时,这个函数将成为构造函数。如果一个类没有构造函数,则调用基类的构造函数,如果有的话。
------------------
- 用户表(包含三个字段用户编号,用户名和用户密码)
- 用户组表(用户组编号和名字)
- 用户与组的对应关系表(组编号和用户编号)
- 节点表(节点编号,名字,注释,父路径编号,等级)(注:这个表很容易将人搞晕)
- 权限表(组编号,节点编号,父路径编号,等级)
‘RBAC_ROLE_TABLE’=>’role’, //用户角色表
‘RBAC_USER_TABLE’=>’admin’,//管理员账户表
‘RBAC_ACCESS_TABLE’=>’role_access’,//角色权限表
‘RBAC_NODE_TABLE’=>’role_node’,//网站操作节点
access表的level有三个可取得值:(1,2,3)1、项目app;2、项目module类;3、action操作;
RBAC::authenticate();//获取RBAC_USER_TABLE中管理员的账户密码,id进行登录验证
RBAC::saveAccessList//用于检测用户权限的方法(action节点),并保存到Session中
RBAC::getRecordAccessList//取得模块的所属记录访问权限列表(module) 返回有权限的记录ID数组
以下是Tp的rbac的数据表
CREATE TABLE IF NOT EXISTS `joys_access` (
`role_id` smallint(5) unsigned NOT NULL,
`node_id` smallint(5) unsigned NOT NULL,
`level` tinyint(4) NOT NULL,
`pid` smallint(6) NOT NULL,
KEY `role_id` (`role_id`,`node_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
role_id node_id level pid
1 1 1 0
1 2 2 1
1 9 3 2
1 7 3 2
2 7 3 2
1 5 2 1
1 11 3 5
------------------------------------------
CREATE TABLE IF NOT EXISTS `think_node` (
`id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,//名称
`title` varchar(50) DEFAULT NULL,//标题
`status` tinyint(1) DEFAULT '0',//状态
`remark` varchar(255) DEFAULT NULL,//
`sort` smallint(6) unsigned DEFAULT NULL,
`pid` smallint(6) unsigned NOT NULL,
`level` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `level` (`level`),
KEY `pid` (`pid`),
KEY `status` (`status`),
KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
id name title status remark sort pid level
1 Admin 后台管理 1 后台项目 0 0 1
2 Section 单元管理 1 控制器 1 1 2
3 Category 分类管理 1 控制器 2 1 2
4 Article 文章管理 1 控制器 3 1 2
5 Index 后台默认 1 控制器 0 1 2
6 Public 公共管理 1 控制器 0 1 2
7 index 单元列表 1 动作 0 2 3
----------------------------------------
CREATE TABLE IF NOT EXISTS `think_role` (
`id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`pid` smallint(6) DEFAULT NULL,
`status` tinyint(1) unsigned DEFAULT NULL,
`remark` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `pid` (`pid`),
KEY `status` (`status`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
id name pid status remark
1 超级管理员 0 1 超级管理员分组
2 普通管理员 0 1 普通管理员分组
3 注册用户 0 1 注册用户分组
--------------------------------------------
CREATE TABLE IF NOT EXISTS `think_role_user` (
`role_id` mediumint(9) unsigned DEFAULT NULL,
`user_id` char(32) DEFAULT NULL,
KEY `group_id` (`role_id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
role_id user_id
1 1
1 1
1 1
1 1
1 1
1 1
---------------------------------
/**
+----------------------------------------------------------
* +----------------------------------------------------------
* @param integer $authId 用户ID
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
*/
static public function getAccessList($authId)
{
// Db方式权限数据
$db = Db::getInstance(C('RBAC_DB_DSN'));
$table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'),'node'=>C('RBAC_NODE_TABLE'));
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=1 and node.status=1";
$apps = $db->query($sql);
$access = array();
foreach($apps as $key=>$app) {
$appId = $app['id'];
$appName = $app['name'];
// 读取项目的模块权限
$access[strtoupper($appName)] = array();
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=2 and node.pid={$appId} and node.status=1";
$modules = $db->query($sql);
// 判断是否存在公共模块的权限
$publicAction = array();
foreach($modules as $key=>$module) {
$moduleId = $module['id'];
$moduleName = $module['name'];
if('PUBLIC'== strtoupper($moduleName)) {
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
$rs = $db->query($sql);
foreach ($rs as $a){
$publicAction[$a['name']] = $a['id'];
}
unset($modules[$key]);
break;
}
}
// 依次读取模块的操作权限
foreach($modules as $key=>$module) {
$moduleId = $module['id'];
$moduleName = $module['name'];
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
$rs = $db->query($sql);
$action = array();
foreach ($rs as $a){
$action[$a['name']] = $a['id'];
}
// 和公共模块的操作权限合并
$action += $publicAction;
$access[strtoupper($appName)][strtoupper($moduleName)] = array_change_key_case($action,CASE_UPPER);
}
}
return $access;
}
static public function getModuleAccessList($authId,$module) {
// Db方式
$db = Db::getInstance(C('RBAC_DB_DSN'));
$table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'));
$sql = "select access.node_id from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.module='{$module}' and access.status=1";
$rs = $db->query($sql);
$access = array();
foreach ($rs as $node){
$access[] = $node['node_id'];
}
return $access;
}