RBAC:Role Based Access Control:基於角色的訪問控制 需求:php
1. 權限、角色、管理員框架
2 權限管理【無限級】post
注意:權限會被分配給角色,不是管理員!ui
3 角色列表this
添加角色時要給角色分配權限:加密
4spa
管理員列表遞歸
5 系統中默認有一個超級管理員而且不能被刪除【沒法分配權限,擁有全部的權限】md5
6 只有登陸了才能進行後臺rem
7 後臺左側只顯示當前管理員有權限訪問的按鈕
實際操做:
三個主表兩個中間表:
/************RBAC權限表***********/
drop table if exists p40_privilege;
create table p40_privilege
(
id mediumint unsigned not null auto_increment comment 'Id',
pri_name varchar(30) not null comment '權限名稱',
module_name varchar(30) not null default '' comment '模塊名稱',
controller_name varchar(30) not null default '' comment '控制器名稱',
action_name varchar(30) not null default '' comment '方法名稱',
parent_id mediumint unsigned not null default '0' comment '上級權限Id',
primary key(id)
)engine =InnoDB default charset=utf8 comment '權限';
drop table if exists p40_role_pri;
create table p40_role_pri
(
pri_id mediumint unsigned not null comment '權限id',
role_id mediumint unsigned not null comment '角色id',
key pri_id(pri_id),
key role_id(role_id)
)engine=InnoDB default charset=utf8 comment '角色權限';
drop table if exists p40_role;
create table p40_role
(
id mediumint unsigned not null auto_increment comment 'id',
role_name varchar(30) not null comment '角色名稱',
primary key(id)
)engine=InnoDB default charset utf8 comment '角色';
drop table if exists p40_admin_role;
create table p40_admin_role
(
admin_id mediumint unsigned not null comment '管理員id',
role_id mediumint unsigned not null comment '角色id',
key admin_id(admin_id),
key role_id(role_id)
)engine =InnoDB default charset=utf8 comment '管理員角色';
drop table if exists p40_admin;
create table p40_admin
(
id mediumint unsigned not null auto_increment comment 'id',
username varchar(30) not null comment '用戶名',
password char(32) not null comment '密碼',
primary key(id)
)engine=InnoDB default charset utf8 comment '管理員';
insert into p40_admin(username,password) values('admin',md5('admin'));
說明:TP框架中自帶一個RBAC的類:也是要使用五張表,TP只提供了五個表和一個類,這個類只提供了未來對五個表的查詢,可是這五個表的操做還須要咱們本身寫!不須要使用TP的,由於它就沒有提供什麼東西,仍是須要本身寫。
2 使用GII直接生成三個主表的代碼,表間關係的代碼須要咱們本身添加完成!!
生成權限列表:
修改配置文件:
設置爲生成遞歸的代碼
'tableName' => 'p40_privilege', // 表名
'tableCnName' => '權限', // 表的中文名
'moduleName' => 'Admin', // 代碼生成到的模塊
'withPrivilege' => FALSE, // 是否生成相應權限的數據
'topPriName' => '', // 頂級權限的名稱
'digui' => 1, // 是否無限級(遞歸)
'diguiName' => 'pri_name', // 遞歸時用來顯示的字段的名字,如cat_name(分類名稱)
'pk' => 'id', // 表中主鍵字段名稱
/********************* 要生成的模型文件中的代碼 ******************************/
// 添加時容許接收的表單中的字段
'insertFields' => "array('pri_name','module_name','controller_name','action_name','parent_id')",
// 修改時容許接收的表單中的字段
'updateFields' => "array('id','pri_name','module_name','controller_name','action_name','parent_id')",
'validate' => "
去掉搜索
/**************** 搜索字段的配置 **********************/
'search' => array(),
生成代碼:
p40_privilege.php
到此無限級權限完成!
2.2. 再生成管理和角色
修改管理員管理的功能
// 添加前
protected function _before_insert(&$data, $option)
{
$data['password']=md5($data['password']);
}
// 刪除前
protected function _before_delete($option)
{
if($option($option['where']['id']) == 1 )
{
$this->error = '超級管理員沒法刪除';
return FALSE;
}
}
超級管理員不顯示刪除按鈕
<td align="center">
<a href="<?php echo U('edit?id='.$v['id'].'&p='.I('get.p')); ?>" title="編輯">編輯</a>
<?php if($v['id'] >1) : ?>
|
<a href="<?php echo U('delete?id='.$v['id'].'&p='.I('get.p')); ?>" onclick="return confirm('肯定要刪除嗎?');" title="移除">移除</a>
<?php endif; ?>
</td>
3.1 修改表單驗證規則,修改時能夠爲空,添加時不能爲空
array('username', 'require', '用戶名不能爲空!', 1, 'regex', 3),
array('username', '1,30', '用戶名的值最長不能超過 30 個字符!', 1, 'length', 3),
//第6個參數:規則何時生效:1 添加時生效 2 修改時生效 3 全部狀況都生效
array('password', 'require', '密碼不能爲空!', 1, 'regex',1),
如今能夠不填寫密碼了,可是被修改成空:
修改以前判斷一下便可:
// 修改前
protected function _before_update(&$data, $option)
{
if($data['password'])
$data['password']=md5($data['password']);
else
unset($data['password']);
}
權限和角色的關係的代碼
用到的表:
實際操做:
//取出全部的權限
$priModel=D('privilege');
$priData=$priModel->getTree();
// 設置頁面中的信息
$this->assign(array(
'priData'=>$priData,
'_page_title' => '添加角色',
'_page_btn_name' => '角色列表',
'_page_btn_link' => U('lst'),
));
修改角色模型在添加以後:
public function _after_insert($data,$opiton)
{
$priId=I('post.pri_id');
$rpModel=D('role_pri');
foeach($priId as $v)
{
$rpModel->add(array(
'pri_id'=>$v,
'role_id'=>$data['id'],
));
}
}
修改角色模型中的search方法
$data['data'] = $this->alias('a')
->field('a.*,c.pri_name')
->join('left join __ROLE_PRI__ b on a.id = b.role_id
left join __PRIVILEGE__ c on b.pri_id=c.id') ->where($where) ->limit($page->firstRow.','.$page->listRows) ->select(); return $data;