CREATE TABLE IF NOT EXISTS `think_access` ( `role_id` smallint(6) unsigned NOT NULL, `node_id` smallint(6) unsigned NOT NULL, `level` tinyint(1) NOT NULL, `module` varchar(50) DEFAULT NULL, KEY `groupId` (`role_id`), KEY `nodeId` (`node_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `think_node` ( `id` smallint(6) unsigned NOT NULLAUTO_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; CREATE TABLE IF NOT EXISTS `think_role` ( `id` smallint(6) unsigned NOT NULLAUTO_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 ; CREATE TABLE IF NOT EXISTS `think_role_user` ( `role_id` mediumint(9) unsigned DEFAULTNULL, `user_id` char(32) DEFAULT NULL, KEY `group_id` (`role_id`), KEY `user_id` (`user_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
2.建立节点处理方法(我这里建立了一个独立的控制器RbacController.class.php)add_node和添加节点表单处理方法add_node_hanlde
//添加节点 publicfunction add_node(){ $this->assign('pid',I('get.pid',0,'intval')); $this->assign('level',I('get.pid',1,'intval')); $this->display(); } //添加节点表单处理 publicfunction add_node_hanlde(){ $data=array( //名称(Home模块就是Home,Rbac控制器就Rbac,index方法就是index) 'name'=>I('post.name'), //描述方法的具体作用(Home模块是前台模块,就写前台模块) 'title'=>I('post.title'), //状态 'status'=>I('post.status'), //排序 'sort'=>I('post.sort'), //上级节点id 'pid'=>I('post.pid'), //级别(1就是模块,2就是控制器,3就是方法) 'level'=>I('post.level'), ); if(M('node')->add($data)){ header('Location:'.U('add_node')); }else{ $this->error('操作失败'); }; }
3.建立显示节点方法node
//显示节点列表 publicfunction node(){ //node_list函数递归把节点列表变成“模块->控制器->方法”层次的数组 $this->assign('node_list',node_list(M('node')->select())); $this->display(); } node_list函数 //递归把节点列表变成“模块->控制器->方法”层次的数组 function node_list($arr,$pid=0){ $node_list=array(); foreach($arr as $key => $value) { if($value['pid']==$pid) { $value['child']=node_list($arr,$value['id']); $node_list[]=$value; } } return$node_list; }
4.建立角色处理方法
//添加角色 publicfunction add_role(){ $this->display(); } //添加角色表单处理 publicfunction add_role_hanlde(){ $data=array('name'=>I('post.name'), 'remark'=>I('post.remark'), 'status'=>I('post.status'), ); if(M('role')->add($data)){ header('Location:'.U('role')); }else{ $this->error('操作失败'); }; } //显示角色列表 publicfunction role(){ $this->assign('role',M('role')->select()); $this->display(); }
5.建立配置权限方法
//配置权限 publicfunction access(){ $access=M('node')->select(); $select_access=M('access')->field('node_id')->where(array('role_id'=>$_GET['role_id']))->select(); foreach($access as $key => $value) { foreach($select_access as $key_1 => $value_1) { if($value['id']==$value_1['node_id']) { $access[$key]['access']=1; break; }else{ $access[$key]['access']=0; } } } $this->assign('rid',$_GET['role_id']); $this->assign('access',node_list($access)); $this->display(); } //配置权限表单处理 publicfunction access_hanlde(){ foreach($_POST['access'] as $key => $value) { $temp=explode('_', $value); $data[]=array('role_id'=>$_POST['rid'],'node_id'=>$temp[0],'level'=>$temp[1]); } if(!(M('access')->where(array('role_id'=>$_POST['rid']))->delete())){ $this->error('操作失败'); } if(M('access')->addAll($data)){ header('Location:'.U('role')); }else{ $this->error('操作失败'); } }
6.用户相关方法
//添加用户 public function add_user(){ $this->assign('role',M('role')->select()); $this->display(); } //添加用户 public function add_user_hanlde(){ $data=array('user_name'=>I('post.name'), 'user_pwd'=>I('post.pwd'), 'user_group'=>I('post.group') ); $user_id=M('user')->add($data); if($user_id){ $data=array('role_id'=>I('post.group'), 'user_id'=>$user_id ); if (M('role_user')->add($data)) { header('Location:'.U('user')); }else{ $this->error('操作失败'); } }else{ $this->error('操作失败'); } } //用户列表 public function user(){ $this->assign('user',D('UserView')->select()); $this->display(); }
7.增加配置项
//rbac // 配置文件增加设置 //是否需要认证,设置为true时$rbac::AccessDecision()函数才会根据当前的操作检查权限并返回true或false,,设为false只返回true 'USER_AUTH_ON' => true, //认证类型,2代表每次进行操作的时候都会数据库取出权限(权限更改即时生效),1代表只在登录的时候取出权限(权限更改下次登录时生效) 'USER_AUTH_TYPE' => 1, //认证识别号,执行$rbac::saveAccessList();的时候回用以这个为键值的session去数据库取权限 'USER_AUTH_KEY' => 'user_id', //认证网关,执行$rbac::checkLogin()函数(检查是否登录),如果没有登录,去到这个设置的网址(当前url直接加上这个设置的值) 'USER_AUTH_GATEWAY' =>'/Login', //数据库连接DSN??? //'RBAC_DB_DSN' =>, //角色表名称 'RBAC_ROLE_TABLE' =>'bg_role', //用户表名称(rbac类说的是用户表,其实是用户角色关联表) 'RBAC_USER_TABLE' =>'bg_role_user', //权限表名称 'RBAC_ACCESS_TABLE' =>'bg_access', //节点表名称 'RBAC_NODE_TABLE' =>'bg_node', //定义rbac超级管理员,登录成功之后把用户名和这个值进行比对,一样就是超级管理员 'RBAC_SUPERADMIN' => 'admin', //超级管理员识别,当当前用户是超级管理员时,把键值为这个值的session这个设置为true,当前用户就能进行一切操作 'ADMIN_AUTH_KEY' => 'superadmin',
8.在登录时取出权限
session(C('USER_AUTH_KEY'),$arr['id']); session('name',$arr['name']); session('last_login_time',date('Y-m-d H:i:s',$arr['last_login_time'])); session('ip',$arr['last_login_ip']); //如果用户是超级管理员,则可以进行一切操作 if (session('name')==C('RBAC_SUPERADMIN')) { session(C('ADMIN_AUTH_KEY'),true); } $rbac=new \Org\Util\Rbac(); //取出用户权限信息 $rbac::saveAccessList();
9,建立一个公共控制器,需要验证的模块都继承这个控制器,写一个前置函数,验证当前操作是否有权限
$rbac=new \Org\Util\Rbac(); //检测是否登录,没有登录就打回设置的网关 $rbac::checkLogin(); //检测是否有权限没有权限就做相应的处理 if(!$rbac::AccessDecision()){ echo '<script type="text/javascript">alert("没有权限");</script>'; die(); }
ok