1.在tp文件夹下/Library/Org/Util/Rbac.class.php文件有几个建表的sql语句,复制到数据库执行,表的前缀改成自己的表前缀
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.建立rbac管理类和对应的模板文件
<?php
/**
* Created by PhpStorm.
* User: jin
* Date: 2015/11/12
* Time: 14:44
*/
namespace Home\Controller;
use Think\Controller;
class RbacController extends Controller
{
private $dsn = 'mysql://root:pass@127.0.0.1:3306/rbac';
// 添加节点
function addNode()
{
$this->assign('pid',I('get.pid',0,'intval'));
$this->assign('level',I('get.level',1,'intval'));
$this->display();
}
function addNodeHandle()
{
if(!preg_match('/^[a-zA-z][a-zA-z0-9_]+$/i',I('post.name')))
{
$this->error('名称错误');
}
$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()->db(1,$this->dsn)->table('think_node')->add($data)){
header('Location:'.U('nodeList'));
}else{
$this->error('操作失败');
}
}
//显示节点关系的表,便于查看
//显示节点列表
public function nodeList(){
//node_list函数递归把节点列表变成“模块->控制器->方法”层次的数组
$nodeList = node_list(M()->db(1,$this->dsn)->table('think_node')->select());
// dump($nodeList);
$this->assign('nodeList',$nodeList);
$this->display();
}
//添加角色
function addRole()
{
$this->display();
}
function addRoleHandle()
{
if(!preg_match('/^[a-zA-z][a-zA-z0-9_]+$/i',I('post.name')))
{
$this->error('名称错误');
}
$data=array(
'name'=>I('post.name'),
'remark'=>I('post.remark'),
'status'=>I('post.status'),
);
if(M()->db(1,$this->dsn)->table('think_role')->add($data)){
header('Location:'.U('roleList'));
}else{
$this->error('操作失败');
};
}
function roleList()
{
$this->assign('roleList',M()->db(1,$this->dsn)->table('think_role')->select());
$this->display();
}
//权限操作
//配置权限
public function editAccess(){
if(empty($_GET['roleId']))
{
E('缺少参数');
}
$access = M()->db(1,$this->dsn)->table('think_node')->select();
$select_access=M()->db(1,$this->dsn)->table('think_access')->field('node_id')->where(array('role_id'=>$_GET['roleId']))->select();
foreach($access as $key => $value) {
foreach($select_access as $key_1 => $value_1) {
if($value['id']==$value_1['node_id']) {
$access[$key]['access'] = 'checked';
break;
}else{
$access[$key]['access'] = '';
}
}
}
$this->assign('roleId',$_GET['roleId']);
$this->assign('nodeList',node_list($access));
$this->display();
}
//配置权限表单处理
public function editAccessHanlde(){
foreach($_POST['nodeId'] as $key => $value) {
$temp=explode('_', $value);
$data[]=array('role_id'=>$_POST['roleId'],'node_id'=>$temp[0],'level'=>$temp[1]);
}
$res = M()->db(1,$this->dsn)->table('think_access')->where(array('role_id'=>$_POST['roleId']))->delete();
if($res === false){
$this->error('操作失败');
}
if($data)
{
$res = M()->db(1,$this->dsn)->table('think_access')->addAll($data);
}
if($res !== false){
header('Location:'.U('roleList'));
}else{
$this->error('操作失败');
}
}
//用户管理
//添加用户
public function addUser(){
$this->assign('roleList',M()->db(1,$this->dsn)->table('think_role')->select());
$this->display();
}
//添加用户
public function addUserHandle(){
$data=array(
'user_name'=>I('post.name'),
'user_pwd'=>I('post.pwd')
);
$userId=M()->db(1,$this->dsn)->table('think_user')->add($data);
if($userId){
$data=array(
'role_id'=>I('post.roleId'),
'user_id'=>$userId
);
if (M()->db(1,$this->dsn)->table('think_role_user')->add($data) !== false) {
header('Location:'.U('userList'));
}else{
$this->error('操作失败');
}
}else{
$this->error('操作失败');
}
}
//用户列表
public function userList(){
$sql = <<<sql
SELECT a.*,c.*
FROM
think_user as a
JOIN
think_role_user as b
ON
a.user_id = b.user_id
JOIN
think_role as c
ON
b.role_id = c.id
sql;
$this->assign('userList',M()->db(1,$this->dsn)->query($sql));
$this->display();
}
}
3.配置文件,thinkphp配置文件里面加上
<?php
return array(
//'配置项'=>'配置值'
//rbac
// 配置文件增加设置
//是否需要认证,设置为true时$rbac::AccessDecision()函数才会根据当前的操作检查权限并返回true或false,,设为false只返回true
'USER_AUTH_ON' => true,
//认证类型,2代表每次进行操作的时候都会数据库取出权限(权限更改即时生效),1代表只在登录的时候取出权限(权限更改下次登录时生效)
'USER_AUTH_TYPE' => 2,
//认证识别号,执行$rbac::saveAccessList();的时候回用以这个为键值的session去数据库取权限
'USER_AUTH_KEY' => 'userId',
//认证网关,执行$rbac::checkLogin()函数(检查是否登录),如果没有登录,去到这个设置的网址(当前url直接加上这个设置的值)
'USER_AUTH_GATEWAY' =>'/Home/Login/login',
//数据库连接DSN
'RBAC_DB_DSN' =>'mysql://root:pass@127.0.0.1:3306/rbac',
//角色表名称
'RBAC_ROLE_TABLE' =>'think_role',
//用户表名称(rbac类说的是用户表,其实是用户角色关联表)
'RBAC_USER_TABLE' =>'think_role_user',
//权限表名称
'RBAC_ACCESS_TABLE' =>'think_access',
//节点表名称
'RBAC_NODE_TABLE' =>'think_node',
//定义rbac超级管理员,登录成功之后把用户名和这个值进行比对,一样就是超级管理员
'RBAC_SUPERADMIN' => 'admin',
//超级管理员识别,当当前用户是超级管理员时,把键值为这个值的session这个设置为true,当前用户就能进行一切操作
'ADMIN_AUTH_KEY' => 'superadmin',
//开启游客访问
'GUEST_AUTH_ON' => true,
//游客用户id
'GUEST_AUTH_ID' => 3,
///* 数据库设置 */
);
4.在登陆的时候取出权限信息
$userInfo = M()->db(1,C('RBAC_DB_DSN'))->table('sn_user')->where(array('user_name'=>I('post.name'),'user_pwd'=>I('post.pwd')))->find();
if($userInfo)
{
session(C('USER_AUTH_KEY'),$userInfo['user_id']);
session('userInfo',$userInfo);
//如果用户是超级管理员,则可以进行一切操作
if ($userInfo['user_name']==C('RBAC_SUPERADMIN')) {
session(C('ADMIN_AUTH_KEY'),true);
}
$rbac = new \Think\Org\Util\Rbac();
//取出用户权限信息
$rbac::saveAccessList();
}
5.在需要的权限控制的方法里面验证,可以设置在控制器的_initialize方法里面
$rbac=new \Think\Org\Util\Rbac();
//检测是否登录,没有登录就打回设置的网关
$rbac::checkLogin();
//检测是否有权限没有权限就做相应的处理
if(!$rbac::AccessDecision()){
$this->redirect('Home/Login/login');
// echo "access";
}
ok