Rbac,基于角色的权限管理系统,可以很好的管理后台,需要5张表,Thinkphp提供了4张,分别是,角色表,节点表,权限表,角色和用户的中间表。我们需要自己创建一张用户表。
TP提供的4张表:
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 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; 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 ; 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;
我们需要把表前缀改成自己需要的,这里我改成hd_.
表创建好之后,首先写角色表,因为它和其他4个表都有关联,角色表和用户的多对多的关系,角色表和节点表也是多对多的关系
所以的表都是从添加开始的,:
1,我们先添加角色表,之后转到角色列表
php code
//角色列表 public function role(){ $this->role=M(‘role‘)->select(); $this->display(); } //添加角色 public function addRole(){ $this->display(); } //添加角色处理 public function addRoleHandle(){ if(M(‘role‘)->add(I(‘post.‘))){ //接受参数并添加进数据库 $this->success(‘添加成功‘,U(MODULE_NAME.‘/Rbac/role‘)); }else{ $this->error(‘添加失败‘); } }
html
添加角色
<form action=‘{:U(MODULE_NAME."/Rbac/addRoleHandle")}‘ method=‘post‘> <table class=‘table‘> <tr><td colspan=‘2‘ align=‘right‘>添加角色</td></tr> <tr><td align=‘right‘>角色名称</td><td><input type=‘text‘ name=‘name‘ /></td></tr> <tr><td align=‘right‘>角色描述</td><td><input type=‘text‘ name=‘remark‘ /></td></tr> <tr><td align=‘right‘>是否开启</td><td><input type=‘radio‘ name=‘status‘ value=1 checked=‘checked‘ />开启 <input type="radio" name=‘status‘ value=0>关闭</td></tr> <tr><td colspan=‘2‘ align=‘center‘><input type=‘submit‘ value=‘添加‘ /></td></tr> </table> </form>
角色列表
<table class=‘table‘> <tr><th colspan=‘5‘>角色列表</th></tr> <tr> <th>ID</th> <th>角色名称</th> <th>角色描述</th> <th>开启状态</th> <th>操作</th> </tr> <foreach name=‘role‘ item=‘v‘> <tr> <th>{$v.id}</th> <th>{$v.name}</th> <th>{$v.remark}</th> <th><if condition=‘$v["status"]‘>开启<else/>关闭</if></th> <th><a href=‘{:U(MODULE_NAME."/Rbac/access",array("id"=>$v["id"]))}‘>权限配置</a></th> </tr> </foreach>
2 添加节点,之后转到节点表
php code
//节点列表 public function node(){ $node= M(‘node‘)->order(‘id‘)->select(); $this->node=node_merge($node); //递归重组信息为多维数组, 目的是,pid和id相等的情况下,把pid的节点信息作为id节点信息的子节点压到id的节点信息中 //一个表的压缩,模型是指2个表直接的组合 $this->display(); } //添加节点 public function addNode(){ $this->level=I(‘get.level‘,‘1‘,‘intval‘); $this->pid=I(‘get.pid‘,‘0‘,‘intval‘); switch ($this->level){ case 1:$this->title=‘应用‘; break; case 2:$this->title=‘控制器‘; break; case 3:$this->title=‘方法‘; break; } $this->display(); } //添加节点处理 public function addNodeHandle(){ if(M(‘node‘)->add(I(‘post.‘))){ $this->success(‘添加成功‘,U(MODULE_NAME.‘/Rbac/node‘)); }else{ $this->error(‘添加失败‘); } }
添加节点
<form action=‘{:U(MODULE_NAME."/Rbac/addNodeHandle")}‘ method=‘post‘> <table class=‘table‘> <tr><td colspan=‘2‘ align=‘right‘>添加节点</td></tr> <tr> <td align=‘right‘>{$title}名称</td><td><input type=‘text‘ name=‘name‘ /></td> </tr> <tr> <td align=‘right‘>{$title}描述</td><td><input type=‘text‘ name=‘remark‘ /></td> </tr> <tr> <td align=‘right‘>是否开启</td><td><input type=‘radio‘ name=‘status‘ checked=‘checked‘ value=1 />开启<input type=‘radio‘ name=‘status‘ value=0 />关闭</td> </tr> <tr><td colspan=‘2‘ align=‘center‘><input type=‘submit‘ value=‘添加‘ /></td></tr> <input type=‘hidden‘ name=‘pid‘ value={$pid} /> <input type=‘hidden‘ name=‘level‘ value={$level} /> </table> </form>
节点列表
<a href=‘{:U(MODULE_NAME."/Rbac/addNode")}‘>[添加应用]</a><br/> <foreach name=‘node‘ item=‘v‘> {$v.remark}<a href=‘{:U(MODULE_NAME."/Rbac/addNode",array("pid"=>$v["id"],"level"=>2))}‘>【添加控制器】</a><br/> <foreach name=‘v.child‘ item=‘c‘> {$c.remark}<a href=‘{:U(MODULE_NAME."/Rbac/addNode",array("pid"=>$c["id"],"level"=>3))}‘>[添加方法]</a><br/> <foreach name=‘c.child‘ item=‘m‘> {$m.remark}【<a href=‘#‘>修改</a>】【<a href=‘#‘>删除</a>】<br/> </foreach> </foreach> </foreach>
3,给角色配置权限
//给角色配置权限 public function access(){ $field=array(‘id‘,‘remark‘,‘pid‘,‘level‘); $node=M(‘node‘)->field($field)->select(); $this->rid=$_GET[‘id‘]; $access=M(‘access‘)->where(array(‘role_id‘=>$_GET[‘id‘]))->getField(‘node_id‘,true); $this->node=node_merge($node,$access); //显示用户原本就有的权限,把access压入每一个表中作为标记,1表示有,0表示没有 $this->display(); } //配置权限处理 public function accessHandle(){ $access=I(‘post.access‘); $arr=array(); foreach ($access as $v){ $res=explode(‘_‘,$v); $arr[]=array( ‘role_id‘=>I(‘post.rid‘), ‘node_id‘=>$res[0], ‘level‘=>$res[1], ); } $where=array(‘role_id‘=>I(‘post.rid‘)); M(‘access‘)->where($where)->delete(); //先删除原有权限,再添加新的权限 if(M(‘access‘)->addAll($arr)){ $this->success(‘添加成功‘,U(MODULE_NAME.‘/Rbac/role‘)); }else{ $this->error(‘添加失败‘); } }
配置权限
<form action=‘{:U(MODULE_NAME."/Rbac/accessHandle")}‘ method=‘post‘> <foreach name=‘node‘ item=‘v‘> {$v.remark}<input type=‘checkbox‘ name=‘access[]‘ value=‘{$v["id"]}_1‘ <if condition=‘$v["access"]‘>checked=‘checked‘</if> /> <br/> <foreach name=‘v.child‘ item=‘c‘> {$c.remark}<input type=‘checkbox‘ name=‘access[]‘ value=‘{$c["id"]}_2‘<if condition=‘$c["access"]‘>checked=‘checked‘</if> /><br/> <foreach name=‘c.child‘ item=‘m‘> {$m.remark}<input type=‘checkbox‘ name=‘access[]‘ value=‘{$m["id"]}_3‘<if condition=‘$m["access"]‘>checked=‘checked‘</if> /><br/> </foreach> </foreach> </foreach> <input type=‘hidden‘ name=‘rid‘ value={$rid} /> <input type=‘submit‘ value=‘配置‘ /> </form>
4,添加用户,转到用户列表,添加用户的同时选择角色
//用户列表 public function user(){ $this->user=D(‘BlogRelation‘)->field(‘password‘,true)->relation(true)->select();//用户和角色的多对多关系,是为了在一个页面显示而建立的, //如果要在一个页面显示角色所拥有的权限,页建立一个多对多的模型 $this->display(); } //添加用户 public function addUser(){ $this->role=M(‘role‘)->select(); $this->display(); } //添加用户处理 public function addUserHandle(){ $user=array( ‘username‘=>I(‘username‘), ‘password‘=>I(‘password‘,‘‘,md5), ‘logintime‘=>time(), ‘loginip‘=>get_client_ip(), ); $arr=array(); if($user_id=M(‘user‘)->add($user)){ foreach (I(‘post.id‘) as $v){ $arr[]=array( ‘user_id‘=>$user_id, ‘role_id‘=>$v, ); } } if(M(‘role_user‘)->addAll($arr)){ $this->success(‘添加成功‘,U(MODULE_NAME.‘/Rbac/user‘)); }else{ $this->error(‘添加失败‘); } }
添加用户
<body> <form action=‘{:U(MODULE_NAME."/Rbac/addUserHandle")}‘ method=‘post‘> <table class=‘table‘> <tr> <td colspan=‘2‘ align=‘right‘>添加用户</td> </tr> <tr><td align=‘right‘>用户名</td><td><input type=‘text‘ name=‘username‘ /></td></tr> <tr><td align=‘right‘>用户密码</td><td><input type=‘password‘ name=‘password‘ /></td></tr> <tr><td align=‘right‘>所属角色</td><td> <foreach name=‘role‘ item=‘v‘> <input type=‘checkbox‘ name=‘id[]‘ value=‘{$v["id"]}‘ />{$v.name}({$v.remark}) </foreach> </td></tr> <tr><td colspan=‘2‘ align=‘center‘><input type=‘submit‘ value=‘添加‘ /></td></tr> </table> </form>
用户列表
<form> <table class=‘table‘> <tr> <th>ID</th> <th>用户名</th> <th>上次登陆时间</th> <th>上次登陆IP</th> <th>锁定状态</th> <th>用户所属组别</th> <th>操作</th> </tr> <foreach name=‘user‘ item=‘v‘> <tr> <td>{$v.id}</td> <td>{$v.username}</td> <td>{$v.logintime|date=‘Y-m-d H:i‘,###}</td> <td>{$v.loginip}</td> <td> <if condition=‘$v["lock"]‘>锁定<else/>开启</if></td> <td> <if condition=‘$v["username"] eq "admin"‘>超级管理员</if> <foreach name=‘v.role‘ item=‘r‘> {$r.name}({$r.remark}) </foreach> </td> <td><a href=‘#‘>锁定</a></td> </tr> </foreach> </table> </form>
配置信息
//Rbac配置 ‘REAC_SUPERADMIN‘=>‘admin‘, //超级管理员名称 ‘ADMIN_AUTH_KEY‘=>‘superadmin‘, //超级管理员识别 ‘USER_AUTH_ON‘ =>true, //是否开启验证 ‘USER_AUTH_TYPE‘=>1, //验证类型(1:登陆验证 2:时时验证) ‘USER_AUTH_KEY‘=>‘uid‘, //用户认证识别号 ‘NOT_AUTH_MODULE‘=>‘Index,Login‘, // 无需认证的控制器 ‘NOT_AUTH_ACTION‘=>‘‘, //无需认证的方法 ‘RBAC_ROLE_TABLE‘=>‘hd_role‘, // 角色表名称 ‘RBAC_USER_TABLE‘=>‘hd_role_user‘, //角色与用户的中间表名称 ‘RBAC_ACCESS_TABLE‘=>‘hd_access‘, //权限表名称 ‘RBAC_NODE_TABLE‘=>‘hd_node‘, //节点名称
最后,要通过Rbac类完成角色权限认证
//用户权限配置 $Rbac=new \Org\Util\Rbac(); $Rbac::saveAccessList(); // p($_SESSION);die;
public function _initialize(){ if(!isset($_SESSION[C(‘USER_AUTH_KEY‘)])){ $this->redirect(MODULE_NAME.‘/Login/index‘); } if(C(‘USER_AUTH_ON‘)){ $RBAC= new \Org\Util\Rbac(); $RBAC::AccessDecision()||$this->error(‘没有权限‘); } }
都是些没用的,浪费博客园的空间和流量了,这样可以基本完成角色权限系统,
原文:http://www.cnblogs.com/hhfhmf/p/4719818.html