菜鸟的我做权限管理模块做了将近五天~~汗颜
一直有要求做权限管理,第一次做权限管理,真的挺坑的~
下面吧做的权限管理步骤写分享下,大神就不必看了,惭愧!
首先
建数据表,权限主要围绕着五张表
think_mange_user用户表 think_access 权限表 think_node节点 think_role角色表 think_role_user角色用户关系表
一个用户对应着多个角色;一个角色可以属于对个用户;是多对多的关系,需要用个中间表即role_user表;
一个角色可以有多个权限;一个权限可以属于多个用户;是多对多的关系,需要有个中间表即access表;
建立数据表 表查询
tp3.2中有框架给的Rbac类,打开 项目下的ThinkPHP\Library\Org\Util\Rbac.class.php
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;
直接数据库中表查询生成表 think_access 权限表 think_node节点 think_role角色表 think_role_user角色用户关系表,手动创建用户表manage_user
我是根据项目走的所以我的表名均改了 teach_前缀
参考别人写的流程,新建以下模块及其控制器
①【添加角色 → 角色列表】 →
提供参考
添加角色模块addRole.html
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>广告管理</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<body>
<div id="content">
<div id="breadcrumb">
<a href="index.html" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="roleList.html">角色管理</a>
<a href="#" class="current">添加角色</a>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div class="widget-box">
<div class="widget-title">
<span class="icon">
<i class="icon-align-justify"></i>
</span>
<h5>添加权限</h5>
<!-- <span class="label label-important">48 notices</span> -->
</div>
<div class="widget-content nopadding">
<form class="form-horizontal" method="post" action="{:U('Rbac/addRoleHandle')}" name="basic_validate" id="basic_validate" novalidate="novalidate" enctype='multipart/form-data'>
<div class="control-group">
<label class="control-label">角色名称</label>
<div class="controls">
<input type="text" name="name" id="name"/>
<span style="margin-left: 10px;color: red" id="aname"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">角色描述</label>
<div class="controls">
<input type="text" name="remark" id="remark"/>
<span style="margin-left: 10px;color: red" id="aname"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">是否开启</label>
<div class="controls">
<label style="display:block;float:left;width:100px;">
<input type="radio" name="status" style="opacity: 0;" checked="checked" value="1"> 是
</label>
<label style="display:block;float:left;width:100px;">
<input type="radio" name="status" style="opacity: 0;" value="0">否
</label>
</div>
<input type="hidden" name="pid" value="">
</div>
<div class="form-actions">
<input type="submit" id="advertAdd" value="提交" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
角色列表模块roleList.html
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>角色管理</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<body>
<div id="content">
<div id="breadcrumb">
<a href="#" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="#" class="current">角色列表</a>
</div>
<div class="container-fluid">
<div class="widget-box">
<div class="widget-title">
<div class="widget-title">
<a href="{:U('Rbac/addRole')}" style="text-decoration:none;color:white">
<button class="btn btn-success" style="margin-left:10px;margin-top:3px;">添加角色</button>
</a>
</div>
</div>
<div class="widget-content nopadding">
<table class="table table-bordered table-striped with-check">
<thead>
<tr>
<th>id</th>
<th>角色名称</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<volist name="role" id="v">
<tr>
<td>{$v.id}</td>
<td>{$v.name}</td>
<td><if condition="$v['status']">
开启
<else/>
关闭
</if>
</td>
<td>
<a href='{:U("Rbac/access","id=$v[id]")}'>
<button class="btn btn-danger"><i class="icon-white"></i> 配置权限</button>
</td>
</tr>
</volist>
</tbody>
</table>
</div>
</div>
<script src="/Public/js/select2.min.js"></script>
<script src="/Public/login/layers/layer.js"></script>
</div>
</div>
</body>
</html>
②【权限列表 → 分配权限】 →
权限列表nodeList.html
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>权限管理</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<body>
<div id="content">
<div id="breadcrumb">
<a href="#" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="#" class="current">权限列表</a>
</div>
<div class="container-fluid">
<div class="widget-box">
<div class="widget-title">
<div class="widget-title">
<a href="{:U('Rbac/addNode')}" style="text-decoration:none;color:white">
<button class="btn btn-success" style="margin-left:10px;margin-top:3px;">添加权限</button>
</a>
</div>
</div>
<div class="widget-content nopadding">
<table class="table table-bordered table-striped with-check">
<thead>
<tr>
<th>id</th>
<th>权限结构</th>
<th>名称</th>
<th>排序</th>
<th>类型</th>
<!-- <th>状态</th> -->
<th>操作</th>
</tr>
</thead>
<tbody>
<volist name="node" id="v">
<tr>
<td>{$v.id}</td>
<td><p style="text-indent:{$v['level']*20}px">*{$v.title}</p></td>
<td>{$v.name}</td>
<td>{$v.sort}</td>
<td>
<if condition="$v['level'] eq 1">
项目
<elseif condition="$v['level'] eq 2"/>
<span style="color:green">模块</span>
<else/>
<span style="color:red">操作</span>
</if>
<td>
<a href="#" onclick="del(this)" id="{$v.id}">
<button class="btn btn-danger"><i class="icon-remove icon-white"></i>删除</button>
</a>
</td>
</tr>
</volist>
</tbody>
</table>
</div>
</div>
<script src="/Public/js/select2.min.js"></script>
<script src="/Public/login/layers/layer.js"></script>
<script type="text/javascript">
function del (me) {
var id=$(me).attr('id');
layer.confirm('确定要删除权限列表吗?', {
btn: ['确定','取消'], //按钮
shade:false, //不显示遮罩
offset: ['300px', '600px']
}, function(){
$.post("{:U('Rbac/deleteNode')}", {rid:id}, function(res) {
if(res.state == 1) {
layer.msg(res.message, {icon: 2, time: 1000,offset: ['300px', '600px']});
} else {
layer.msg(res.message, {icon:1, time: 1000,offset: ['300px', '600px']});
}
setTimeout(function() {
location.reload();
}, 1000);
});
}, function(){
layer.msg('取消了删除!', {time: 1000, offset: ['300px', '600px']});
})
}
</script>
</div>
</div>
</body>
</html>
添加权限addNode.html
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>广告管理</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<body>
<div id="content">
<div id="breadcrumb">
<a href="index.html" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="nodeList.html">权限管理</a>
<a href="#" class="current">添加权限</a>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div class="widget-box">
<div class="widget-title">
<span class="icon">
<i class="icon-align-justify"></i>
</span>
<h5>添加权限</h5>
<!-- <span class="label label-important">48 notices</span> -->
</div>
<div class="widget-content nopadding">
<form class="form-horizontal" method="post" action="{:U('Rbac/addNodeHandle')}" name="basic_validate" id="basic_validate" novalidate="novalidate" enctype='multipart/form-data'>
<div class="control-group">
<label class="control-label">英文名称</label>
<div class="controls">
<input type="text" name="name" id="name"/>
<span style="margin-left: 10px;color: red" id="aname"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">显示中文名称</label>
<div class="controls">
<input type="text" name="title" id="title"/>
<span style="margin-left: 10px;color: red" id="aname"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">状态</label>
<div class="controls">
<label style="display:block;float:left;width:100px;">
<input type="radio" name="status" style="opacity: 0;" checked="checked" value="1"> 启用
</label>
<label style="display:block;float:left;width:100px;">
<input type="radio" name="status" style="opacity: 0;" value="0">禁用
</label>
</div>
</div>
<div class="control-group">
<label class="control-label">类型</label>
<div class="controls">
<select name="level" id="level">
<option value="1">项目</option>
<option value="2">模块</option>
<option value="3">操作</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">父节点</label>
<div class="controls">
<select name="pid">
<option value="0">根节点</option>
<volist name="node" id="v">
<if condition="$v.level eq 1">
<option value="{$v.id}">{$v.title}</option>
<else/>
<option value="{$v.id}"> |_{$v.title}</option>
</if>
</volist>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">排序</label>
<div class="controls">
<input type="text" name="sort" id="sort"/>
</div>
</div>
<div class="form-actions">
<input type="submit" id="advertAdd" value="提交" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
配置权限模块
③【配置用户权限】 →
添加节点模块access.html
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>广告管理</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="/Public/css/bootstrap.min.css" />
<link rel="stylesheet" href="/Public/css/bootstrap-responsive.min.css" />
<link rel="stylesheet" href="/Public/css/colorpicker.css" />
<link rel="stylesheet" href="/Public/css/datepicker.css" />
<link rel="stylesheet" href="/Public/css/uniform.css" />
<link rel="stylesheet" href="/Public/css/unicorn.main.css" />
<link rel="stylesheet" href="/Public/css/unicorn.grey.css" class="skin-color" />
<script src="/Public/js/jquery.min.js"></script>
<script src="/Public/js/unicorn.tables.js"></script>
</head>
<script type="text/javascript">
function exe(me){
var level=$(me).attr('level');
if(level==1){
var str='_';
var inputs=$('input[value*='+str+']');
$(me).attr('checked')?inputs.attr('checked',true):inputs.removeAttr('checked');
}
else if(level==2){
var rr=$(me).attr('id');
var inputs=$('input[pid='+rr+']');
$(me).attr('checked')?inputs.attr('checked',true):inputs.removeAttr('checked');
}
else if(level==3){
if($(me).attr('checked')){
var pid=$(me).attr('pid');
$('input[id='+pid+']').attr('checked',true);
var ppid=$('input[id='+pid+']').attr('pid');
$('input[id='+ppid+']').attr('checked',true);
}else{
}
}
}
</script>
<body>
<div id="content">
<div id="breadcrumb">
<a href="index.html" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="advert/advert">广告列表</a>
<a href="#" class="current">添加广告</a>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div class="widget-box">
<div class="widget-title">
<span class="icon">
<i class="icon-align-justify"></i>
</span>
<h5>配置权限</h5>
</div>
<div class="widget-content nopadding">
<form action="{:U('Rbac/accessHandle')}" method="POST">
<input type="hidden" name="rid" value="{$rid}">
<table class="table table-bordered table-striped with-check">
<thead>
<tr>
<td>
你正在为<span style="font-weight:bold;color:blue">{$name}</span>配置权限</div>
<volist name="node" id="v">
<p style="text-indent:{$v['level']*20}px;
<if condition='$v.level eq 3'>float:left;margin-right:-40px;<else/>clear:both;</if>">
<input id="{$v.id}" type="checkBox" value="{$v.id}_{$v.level}" pid="{$v.pid}" level="{$v.level}" name="access[]" onclick="exe(this)"<if condition="$v['access']">checked="checked"</if>/>
<if condition="$v['level'] eq 1">
<span style="font-size:10px;color:red;font-weight:bold">[项目]</span>
<elseif condition="$v.level eq 2"/>
<span style="font-size:10px;color:green;font-weight:bold">[模块]</span>
</if>
<span name="name" value="{$v.id}">{$v.title}</span>
</p>
</volist>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-actions">
<input type="submit" id="advertAdd" value="提交" class="btn btn-primary" />
</div></td>
</tr>
</volist>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
④【添加用户 → 用户列表 】 →
用户列表模块hand.html
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>管理员列表</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<script type="text/javascript">
function del(a){
var nid = a;
$.post("{:U('Rbac/handDel')}?uid="+nid,function(res) {
if(res.state == 1) {
layer.msg(res.message, {icon: 1, time: 1000,offset: ['300px', '600px']});
} else {
layer.msg(res.message, {icon:2, time: 1000,offset: ['300px', '600px']});
}
setTimeout(function() {
location.reload();
}, 1000);
})
}
</script>
<script src="/Public/js/select2.min.js"></script>
<script src="/Public/login/layers/layer.js"></script>
<body>
<div id="content">
<div id="breadcrumb">
<a href="#" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="#" class="current">管理员列表</a>
</div>
<div class="container-fluid">
<div class="widget-box">
<div class="widget-title">
<a href="{:U('Rbac/handAdd')}" style="text-decoration:none;color:white">
<button class="btn btn-success" style="margin-left:10px;margin-top:3px;">添加管理员</button>
</a>
</div>
<div class="widget-content nopadding">
<table class="table table-bordered table-striped with-check">
<thead>
<tr>
<th><i class="icon-resize-vertical"></i></th>
<th>管理组</th>
<th>管理员</th>
<th>性别</th>
<th>email</th>
<th>注册时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<volist name="manage_user" id="v">
<tr>
<td>{$v.manage_user_id}</td>
<!-- <volist name="v['role_group']" id="v1"> -->
<td>{$v[role_group][0]}</td>
<!-- </volist> -->
<td>{$v.username}</td>
<td><eq name="v.sex" value="1">男
<else/> 女
</eq></td>
<td>{$v.email}</td>
<td>{$v.ragdate}</td>
<td class="taskOptions" style="width:30%">
<a href='{:U("Rbac/handEdit","id=$v[manage_user_id]")}'>
<button class="btn btn-primary"><i class="icon-pencil icon-white"></i> Edit</button>
</a>
<if condition="$v.username eq session(username)">
<a href="javascript:;" >
<button class="btn btn-danger"><i class="icon icon-user icon-white"></i> 登录...</button>
</a>
<else/>
<a href="javascript:;" onclick="del('{$v.manage_user_id}')">
<button class="btn btn-danger"><i class="icon-remove icon-white"></i> Delete</button>
</a>
</if>
</td>
</tr>
</volist>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
添加用户模块handAdd
<include file="View:view" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>添加管理员</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
<script src="/Public/js/select2.min.js"></script>
<script src="/Public/login/layers/layer.js"></script>
<body>
<div id="content">
<div id="breadcrumb">
<a href="#" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a>
<a href="#" class="current">添加管理员</a>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div class="widget-box">
<div class="widget-title">
<span class="icon">
<i class="icon-align-justify"></i>
</span>
<h5>添加管理员</h5>
</div>
<div class="widget-content nopadding">
<form class="form-horizontal" method="post" action="{:U('Rbac/handAddHandle')}" name="password_validate" id="password_validate" novalidate="novalidate">
<div class="control-group">
<label class="control-label">管理组</label>
<div class="controls">
<select name="role_id" style="width:20%">
<volist name="role" id="v">
<option value="{$v.id}">{$v.name}</option>
</volist>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">管理员</label>
<div class="controls">
<input type="text" name="username" id="required">
</div>
</div>
<div class="control-group">
<label class="control-label">密码</label>
<div class="controls">
<input type="password" name="pwd" id="pwd">
</div>
</div>
<div class="control-group">
<label class="control-label">重复密码</label>
<div class="controls">
<input type="password" name="pwd2" id="pwd2">
</div>
</div>
<div class="control-group">
<label class="control-label">性別</label>
<div class="controls">
<label style="display:block;float:left;width:100px;">
<input type="radio" name="sex" style="opacity: 0;" checked="checked" value="1"> 男
</label>
<label style="display:block;float:left;width:100px;">
<input type="radio" name="sex" style="opacity: 0;" value="0">女
</label>
</div>
</div>
<div class="control-group">
<label class="control-label">邮箱</label>
<div class="controls">
<input type="text" name="email" id="email">
</div>
</div>
<div class="form-actions">
<input type="submit" id="HandAdd" value="提交" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="/Public/js/jquery.validate.js"></script>
<script src="/Public/js/unicorn.js"></script>
<script src="/Public/js/unicorn.form_validation.js"></script>
</html>
以上模块的方法都写在RbacController.class.php控制器里面
需要注意引用Rbac类
新建Org\Util文件夹下Tree类Tree.class.php
<?php
namespace Org\Util;
class Tree{
static public $treeList=array();
public function create($data,$pid=0){
foreach ($data as $key => $value) {
if($value['pid']==$pid){
self::$treeList[]=$value;
unset($data[$key]);
self::create($data,$value['id']);
}
}
return self::$treeList;
}
}
?>
为了节点权限显示层级 在Org\Util下新建类Tree并在控制器中使用user引入
<?php
namespace Home\Controller;
use Org\Util\Tree;
use Think\Controller;
class RbacController extends ManageController
{
//添加角色
public function addRole()
{
$this->assign("style","rbac");
$this->display("addRole");
}、
//添加角色数据提交
public function addRoleHandle()
{
$data['name']=I('name');
$data['remark']=I('remark');
$data['status']=I('status');
if(M('teach_role')->add($data)){
$this->success('添加成功!');
}
}
//角色列表显示
public function roleList()
{
$this->assign("style","rbac");
$role=M('teach_role')->select();
$this->assign('role',$role);
$this->display("roleList");
}
//权限列表
public function nodeList()
{
$this->assign("style","rbac");
$node=M('teach_node')->order("sort")->select();
$node=Tree::create($node);
$this->assign('node',$node);
$this->display("nodeList");
}
//添加权限
public function addNode()
{
$this->assign("style","rbac");
$node=M('teach_node')->where("level!=3")->order("sort")->select();
$this->assign("node",$node);
$this->display("addNode");
}
// 添加权限表单处理
public function addNodeHandle()
{
$node=M('teach_node');
$node->create();
if($node->add()){
$this->success("添加成功!",U("Rbac/nodeList"));
}
}
// 删除配置
public function deleteNode()
{
$id=I('rid');
$node=M('teach_node')->where('id='.$id)->delete();
if(!$node){
$this->success("删除成功!");
}
}
//管理员列表
public function hand(){
$this->assign("style","rbac");
$manage_user=M('manage_user')
->join("teach_role_user on teach_role_user.user_id=manage_user.manage_user_id")
->select();
$role=M('teach_role')->select();
// dump($manage_user);
// dump($role);exit;
foreach ($manage_user as $key => $value) {
$manage_user[$key]['role_group']=array();
foreach ($role as $x => $y) {
if($manage_user[$key]['role_id']==$role[$x]['id']){
array_push($manage_user[$key]['role_group'],$role[$x]['name']);
}
}
}
$this->assign('manage_user',$manage_user);
$this->display('hand');
}
//添加管理员
public function handAdd(){
$this->assign("style","rbac");
$role=M('teach_role')->select();
$this->assign('role',$role);
$this->display('handAdd');
}
//添加管理员数据提交
public function handAddHandle(){
$data['username']=I('username');
$data['password']=md5(I('pwd'));
$data['sex']=I('sex');
$data['email']=I('email');
$data['ragdate']=date("Y-m-d H:i:s");
$uid=M('manage_user')->add($data);
if($uid){
$role['role_id']=I('role_id');
$role['user_id']=$uid;
M('teach_role_user')->add($role);
$this->success("添加成功!",U('Rbac/hand'));
}else{
$this->error('添加失败!');
}
}
//编辑管理员
public function handEdit(){
$this->assign("style","rbac");
$role=M('teach_role')->select();
$id=$_GET['id'];
$manageEdit=M('manage_user')->where("manage_user_id='%s'",$id)->find();
$role_user=M('teach_role_user')->select();
foreach ($manageEdit as $value) {
$manageEdit['role_id']=array();
foreach ($role_user as $x => $y) {
if($manageEdit['manage_user_id']==$role_user[$x]['user_id']){
array_push($manageEdit['role_id'],$role_user[$x]['role_id']);
}
}
}
$this->assign('manageEdit',$manageEdit);
$this->assign('role',$role);
$this->display('handEdit');
}
public function handEditHandle(){
$id=I('manage_user_id');
$data['username']=I('username');
$data['email']=I('email');
$data['sex']=I('sex');
$role['role_id']=I('role_id');
$role_save=M('teach_role_user')->where('user_id='.$id)->save($role);
$user_save=M('manage_user')->where("manage_user_id='%s'",$id)->save($data);
if($role_save||$user_save){
$this->success("修改成功!",U('Rbac/hand'));
}else{
$this->error('未作修改!');
}
}
public function handDel(){
$id=$_GET['uid'];
if(M('manage_user')->where("manage_user_id='%s'",$id)->delete()){
$this->ajaxReturn(['message'=>'删除成功!','state'=>1]);
}else{
$this->ajaxReturn(['message'=>'删除失败!','state'=>2]);
}
}
//配置权限
public function access(){
$this->assign("style","rbac");
$id=$_GET['id'];
$node=M('teach_node')->order('sort')->select();
$node=Tree::create($node);
$this->name=M('teach_role')->getFieldById($id,'name');
$data=array();//$data用于存放最新属组,里面包含当前用户组诗都存有权限
$access=M('teach_access');
foreach ($node as $value) {
$count=$access->where("role_id='%s' and node_id='%s'",$id,$value['id'])->count();
if($count){
$value['access']=1;
}else{
$value['access']=0;
}
$data[]=$value;
}
$node=$data;
$this->rid=$id;
$this->assign('node',$node);
$this->display();
}
//添加权限角色表
public function accessHandle(){
$rid=I('rid');
$access=M('teach_access')->where("role_id='%s'",$rid)->delete();
if(isset($_POST['access'])){
$data=array();
foreach ($_POST['access'] as $value) {
$tem=explode('_', $value);
$data[]=array(
"role_id"=>$rid,
'node_id'=>$tem[0],
'level'=>$tem[1]
);
}
if(M('teach_access')->addAll($data)){
$this->success('修改成功!',U('Rbac/roleList'));
}
}else{
$this->error("修改失败");
}
}
}
⑤【Rbac 配置】→
接着就该配置rbac了,在config.php中修改
<?php
return array(
"USER_AUTH_ON" => true, //是否开启权限验证(必配)
"USER_AUTH_TYPE" => 1, //验证方式(1、登录验证;2、实时验证)
"USER_AUTH_KEY" => 'authId', //用户认证识别号(必配)
"ADMIN_AUTH_KEY" => 'superadmin', //超级管理员识别号(必配)
"USER_AUTH_MODEL" => 'manage_user', //验证用户表模型 ly_user
// 'USER_AUTH_GATEWAY' => '/Public/login', //用户认证失败,跳转URL
'AUTH_PWD_ENCODER'=>'md5', //默认密码加密方式
"RBAC_SUPERADMIN" => 'admin', //超级管理员名称
"NOT_AUTH_MODULE" => 'Index,Public', //无需认证的控制器
"NOT_AUTH_ACTION" => 'index', //无需认证的方法
'REQUIRE_AUTH_MODULE' => '', //默认需要认证的模块
'REQUIRE_AUTH_ACTION' => '', //默认需要认证的动作
'GUEST_AUTH_ON' => false, //是否开启游客授权访问
'GUEST_AUTH_ID' => 0, //游客标记
"RBAC_ROLE_TABLE" => 'teach_role', //角色表名称(必配)
"RBAC_USER_TABLE" => 'teach_role_user', //用户角色中间表名称(必配)
"RBAC_ACCESS_TABLE" => 'teach_access', //权限表名称(必配)
"RBAC_NODE_TABLE" => 'teach_node', //节点表名称(必配)
);
⑥【登陆】
用户在验证登录后进行数据保存session
在登录控制器中引入Rbac类
use Org\Util\Rbac;
if(session(username)==C('RBAC_SUPERADMIN')){
session(C('ADMIN_AUTH_KEY'),true);
}
session(C('USER_AUTH_KEY'),$manage_user_id);
RBAC::saveAccessList();
让各控制器继承一个公共控制器,自定义
public function _initialize(){
if(!session('?username')){
redirect(U("Login/index"));
}
// 判断是否用户已经登陆
if(!isset($_SESSION[C('USER_AUTH_KEY')])){
$this->redirect('login/index');
}
// 判断是否在无需认证模块中
$notAuth=in_array(MODULE_NAME,explode(',',C('NOT_AUTH_MODULE')))||in_array(MODULE_NAME,explode(',',C('NOT_AUTH_ACTION')));
if(C('USER_AUTH_ON')&&!$notAuth){
//RBAC开始认证
if(!RBAC::AccessDecision()){
// $this->error('没有权限!');
}else{
// echo "有权限!";
// dump(MODULE_NAME.'-'.ACTION_NAME."有权限!");
}
}
$record=M('admin_login_record');
if($sess=$record->where('username="'.session('username').'"')->find()){
if($sess['record_time']>=time()-600&&$sess['ip_address']!=$_SERVER['REMOTE_ADDR']){
$this->error("该账号已在另一个IP地址登录。<br/>请确认账号已经退出且账号信息没有泄漏,在10分钟后重试登录",U("Login/logoutHandle"));
}
$record->where('username="'.session('username').'"')->setField('record_time',time());
}
else{
$this->error("获取登录信息出错");
}
if(session(C('ADMIN_AUTH_KEY'))){
//当用户是超级管理员时
$viewList=D('teach_node')->where("level='%s'",2)->order('sort')->select();
$view=M('teach_node')->order('sort')->select();
foreach ($viewList as $key => $value) {
$viewList[$key]['msg']=array();
foreach ($view as $x => $y) {
if($viewList[$key]['id']==$view[$x]['pid']){
array_push($viewList[$key]['msg'], $view[$x]);
}
}
}
}//当用户不是超级管理员时
else{
// 取出所有权限节点
$viewList=D('teach_node')->where("level='%s'",2)->order('sort')->select();
$view=M('teach_node')->order('sort')->select();
foreach ($viewList as $key => $value) {
$viewList[$key]['msg']=array();
foreach ($view as $x => $y) {
if($viewList[$key]['id']==$view[$x]['pid']){
array_push($viewList[$key]['msg'], $view[$x]);
}
}
}
// 取出当前登陆用户所有模块权限(英文名称)和操作权限(ID)
$module='';
$node_id='';
$access=$_SESSION['_ACCESS_LIST'];
foreach ($access as $key => $value) {
foreach ($value as $x => $y) {
$module=$module.','.$x;
foreach ($y as $x1 => $y1) {
$node_id=$node_id.','.$y1;
}
}
}
foreach ($viewList as $key => $value) {
if(!in_array(strtoupper($value['name']),explode(',',$module))){
unset($viewList[$key]);
}else{
foreach ($value['msg'] as $key1 => $value1) {
if(!in_array(strtoupper($value['id']),explode(',',$node_id))){
unset($viewList[$key]['node'][$key1]);//一层一层下来删除此操作
}
}
}
}
}
//$viewList是筛选出来的有权限的菜单显示左侧菜单
$this->assign('viewList',$viewList);
}
前台菜单模块部分
<ul class="nav btn-group">
<li class="btn btn-inverse dropdown"><a href="#" data-toggle="dropdown" class="dropdown-toggle"><i class="icon icon-user"></i> <span class="text"><?php echo session(username)?></span> <span class="label label-important">1</span> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="<eq name='style' value='pwdEdit'>active</eq>"><a class="sOutbox" title="" href="{:U('index/pwdEdit')}">修改密码</a></li>
</ul>
</li>
<li class="btn btn-inverse"><a title="" href="{:U('login/logoutHandle')}"><i class="icon icon-share-alt"></i> <span class="text">退出</span></a></li>
</ul>
</div>
<div id="sidebar">
<a href="#" class="visible-phone"><i class="icon icon-file"></i> 控制面板</a>
<ul>
<li class="<eq name='style' value='index'>active</eq>"><a href="{:U('index/index')}"><i class="icon icon-home"></i> <span>控制面板</span></a></li>
<volist name="viewList" id="v">
<if condition="$v.msg eq null">
<li class="<eq name='style' value='$v.name'>active</eq>">
<a href="/home/{$v.name}/{$v.name}"><i class="icon icon icon-file"></i> <span>{$v.title}</span></a>
</li>
<else/>
<li class="submenu <eq name='style' value='$v.name'>open active</eq>">
<a href="#"><i class="icon icon-th-list"></i> <span>{$v.title}</span> <span class="label"><?php echo count($v['msg']);?></span></a>
<ul>
<volist name="v['msg']" id="v1">
<li class=""><a href="/home/{$v.name}/{$v1.name}">{$v1.title}</a></li>
</volist>
</ul>
</li>
</if>
</volist>
</ul>
//over~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~