【捷哥浅谈PHP】第七弹 ---- 基于角色的访问控制RBAC
来源:互联网 发布:知乎 双肩包 独立品牌 编辑:程序博客网 时间:2024/06/15 21:27
上文给大家讲解了使用循环输出九九乘法表,逻辑上还是相对简单一些,重在给大家提供一种看程序,解析代码的方法和思路,有什么意见或者建议可以跟帖批斗....
好了,不多说了,本文来给大家介绍一下“基于角色的访问控制 ”,
说到权限,大家就很头疼,怎么样能灵活把控好一个用户的权限,
有些同学会在用户表中加字段或者是在角色表中加相应的权限字段,
这样会有一个问题,做起权限来会感觉特别的蹩脚,而且很不灵活,每增加一种权限就要在数据库中增加一个字段,很不利于项目的迭代开发
那么我们就需要一种非常灵活的设计模式RBAC,即基于角色的访问控制;
我来给大家说下这种设计思想:
首先,我们的需求是判断某一个用户对当前操作的控制器或控制器的方法是否有权限访问,
如果多个用户同时拥有同样的权限,那我们就需要给这些用户指定同一个用户角色,然后只需要通过角色来对操作的访问进行权限控制,
那我们表结构需要这样来设计,这个很重要,如下:
第一张数据表(用户表):
好了,不多说了,本文来给大家介绍一下“基于角色的访问控制 ”,
说到权限,大家就很头疼,怎么样能灵活把控好一个用户的权限,
有些同学会在用户表中加字段或者是在角色表中加相应的权限字段,
这样会有一个问题,做起权限来会感觉特别的蹩脚,而且很不灵活,每增加一种权限就要在数据库中增加一个字段,很不利于项目的迭代开发
那么我们就需要一种非常灵活的设计模式RBAC,即基于角色的访问控制;
我来给大家说下这种设计思想:
首先,我们的需求是判断某一个用户对当前操作的控制器或控制器的方法是否有权限访问,
如果多个用户同时拥有同样的权限,那我们就需要给这些用户指定同一个用户角色,然后只需要通过角色来对操作的访问进行权限控制,
那我们表结构需要这样来设计,这个很重要,如下:
第一张数据表(用户表):
字段名称字段说明id用户ID(主键自增)username用户名password用户密码
第二张数据表(角色表):
字段名称字段说明id用户角色ID(主键自增)name用户角色名称
第三张数据表(节点表):
字段名称字段说明id操作节点ID(主键自增)name操作节点的名称zh_name节点的中文说明
我们使用第三范式来设计关联表,这样做的好处是,避免数据冗余,并且对于一对多,多对一的关系都可以清晰的记录,条理清晰
第四张数据表(节点对应角色表):
字段名称字段说明role_id用户角色ID(外键,关联角色表中的主键ID)note_id操作节点ID(外键,关联节点表中的主键ID)
第五张数据表(用户对应角色表):
字段名称字段说明role_id用户角色ID(外键,关联角色表中的主键ID)user_id用户ID(外键,关联用户表中的主键ID)
通过这五张表就可以对权限进行访问控制,它的具体操作步骤如下:
用户输入用户名密码登录,
通过用户表判断,如果输入的用户名密码不合法,跳回重新登录
如果合法,在用户表中返回用户的ID号,
通过此用户ID号,到用户与角色的关联表中查询出用户的角色ID号,
拿到角色ID号,通过此ID号到角色与节点的关联表中查询出此角色拥有的节点访问权限,
将此权限节点全部存入SESSION中,当用户访问某一个模块的时候,
例如:http://www.lampbroher.net/index.php/stu/index
我们用session中的权限与$_GET['m']与$_GET['a']去对比,
如果$_GET['m']或者$_GET['a']在SESSION中不存在,说明该用户没有此权限,作出处理即可。
参考代码:
RBAC类文件:
- <?php
- /* ---------------------------------------------------------------------------------------
- | RBAC权限控制类
- -----------------------------------------------------------------------------------------
- | 版权所有 lamp兄弟连
- -----------------------------------------------------------------------------------------
- | 作者: 李捷 (lijie@li-jie.me)
- | 最后修改时间: 2012-05-06 18:30
- -----------------------------------------------------------------------------------------
- */
- class Rbac{
- private $node_tablename; //定义私有属性节点表名称
- private $group_auth_tablename; //定义私有属性组权限表名称
- private $group_tablename; //定义私有属性用户组表名称
- private $group_user_tablename; //定义私有属性用户归属组表名称
- private $user_tablename; //定义私有属性用户表名称
- /*
- 构造方法
- @param1 string 节点表名称
- @param2 string 用户权限表名称
- @param3 string 用户组表名称
- @param4 string 用户归属组表名称
- @param5 string 用户表名称
- */
- public function __construct($node_tablename='node',$group_auth_tablename='group_auth',$group_tablename='group',$group_user_tablename='group_member',$user_tablename='member'){
- $this->node_tablename = $node_tablename; //获取节点表名称
- $this->group_auth_tablename = $group_auth_tablename; //获取用户权限表名称
- $this->group_tablename = $group_tablename; //获取用户组表名称
- $this->group_user_tablename = $group_user_tablename; //获取用户归属组表名称
- $this->user_tablename = $user_tablename; //获取用户表名称
- }
- /*
- 设置节点方法
- @param1 string 节点名称
- @param2 string 节点父ID
- @param2 string 节点中文说明
- @return int 插入节点记录成功以后的ID
- */
- public function set_node($name,$pid,$zh_name=''){
- if(!empty($name) && !empty($pid)){
- $node = D($this->node_tablename)->insert(array("name"=>$name,"pid"=>$pid,"zh_name"=>$zh_name));
- }
- return $node;
- }
- /*
- 设置权限方法
- @param1 int 组ID
- @param2 int 节点ID
- @return int 插入权限记录成功以后的ID
- */
- public function set_auth($gid,$nid){
- if(!empty($gid) && !empty($nid)){
- $auth = D($this->group_auth_tablename)->insert(array("gid"=>$gid,"nid"=>$nid));
- }
- return $auth;
- }
- /*
- 获取节点方法
- @param1 int 节点ID
- @return array 获取到节点表的相关信息
- */
- public function get_node($id){
- if(!empty($id)){
- $data = D($this->node_tablename)->field("id,name,pid")->where(array('id'=>$id))->find();
- return $data;
- }else{
- return false;
- }
- }
- /*
- 获取组权限方法
- @param1 int 用户组ID
- @return array 获取到组权限表的相关信息
- */
- public function get_auth($gid){
- if(!empty($gid)){
- $data = D($this->group_auth_tablename)->field("nid")->where(array('gid'=>$gid))->select();
- return $data;
- }else{
- return false;
- }
- }
- /*
- 获取用户组方法
- @param1 int 用户ID
- @return array 获取该用户所对应的用户组id
- */
- public function get_group($uid){
- if(!empty($uid)){
- $data = D($this->group_user_tablename)->field("gid")->where(array('uid'=>$uid))->select();
- return $data;
- }else{
- return false;
- }
- }
- /*
- 获取节点的子节点方法
- @param1 int 节点ID
- @return array 获取该节点所对应的全部子节点
- */
- public function get_cnode($nid){
- if(!empty($nid)){
- $cnode = D($this->node_tablename)->field("name")->where(array('pid'=>$nid))->select();
- return $cnode;
- }else{
- return false;
- }
- }
- /*
- 获取权限方法
- @param1 int 用户ID
- @return array 得到权限列表
- */
- public function get_access($uid){
- if(!empty($uid)){
- //调用获取组信息方法
- $group = $this->get_group($uid);
- //遍历组信息
- foreach($group as $v){
- //将组ID传入获取权限的方法
- $auth = $this->get_auth($v['gid']); //获取该组的权限
- }
- //遍历该组的权限数组
- foreach($auth as $val){
- //将节点的ID传入获取节点信息方法
- $node[] = $this->get_node($val['nid']); //获取节点的相关信息
- }
- //遍历节点数组,并拼装
- foreach($node as $nval){
- if($nval['pid']==0){
- $fnode[] = $nval; //将控制器压入fnode数组
- //$cnode = $this->get_cnode($nval['id']);
- }else{
- $cnode[] = $nval; //将控制器的方法压入cnode数组
- }
- }
- //将控制器数组和控制器数组拼装成一个数组
- foreach($fnode as $fval){
- foreach($cnode as $cval){
- if($cval['pid'] == $fval['id']){
- $access[$fval['name']][] = $cval['name'];
- }
- }
- }
- //返回权限列表数组
- return $access;
- }else{
- return false;
- }
- }
- /*
- 检测权限方法
- @param1 int 用户ID
- @return boolean 权限禁止与否
- */
- public function check($uid){
- if(!empty($uid)){
- //将权限存入到$_SESSION['Access_List']中
- $_SESSION['Access_List'] = $this->get_access($uid);
- if(!empty($_GET['m'])){
- //判断此控制器是否被允许
- if(array_key_exists($_GET['m'],$_SESSION['Access_List'])){
- //判断此控制器的方法是否被允许
- if(in_array($_GET['a'],$_SESSION['Access_List'][$_GET['m']])){
- //允许的话返回真
- return true;
- }else{
- //否则返回假
- return false;
- }
- }else{
- return false;
- }
- }else{
- return false;
- }
- }else{
- //$_SESSION['user_'.$uid]['Access_List'] = 0;
- return false;
- }
- }
- public function show_node(){
- $path = APP_PATH.'/controls/';
- $handle = opendir($path);
- while(false!==($data = readdir($handle))){
- if(is_file($path.$data) && $data!='common.class.php' && $data!='pub.class.php'){
- $controller = str_replace(".class.php",'',$data);
- $res = fopen($path.$data,'r');
- $str = fread($res,filesize($path.$data));
- $pattern = '/function(.*)\(\)/iU';
- preg_match_all($pattern, $str, $matches);
- foreach($matches[1] as $v){
- $v = trim($v);
- $arr[$controller][] = $v;
- }
- }
- }
- closedir($handle);
- return $arr;
- }
- }
初始化类:
- <?php
- /* ---------------------------------------------------------------------------------------
- | 初始化控制器
- -----------------------------------------------------------------------------------------
- | 版权所有 lamp兄弟连
- -----------------------------------------------------------------------------------------
- | 作者: 李捷 (lijie@li-jie.me)
- | 最后修改时间: 2012-05-06 18:30
- -----------------------------------------------------------------------------------------
- */
- class Common extends Action {
- /*
- 初始化方法
- */
- public function init(){
- //如果SESSION为空,则跳转
- if(empty($_SESSION['user_login'])){
- $this->redirect("pub/index");
- }
- $a = new rbac();
- if(!$a->check($_SESSION['user_info']['id'])){
- echo "<script>alert('您没有此权限!')</script>";
- exit("<script>document.write('<span style=\'font-size:40px;font-weight:bold\'>Access Forbidden');alert('您没有此权限!');</script>");
- $this->redirect("pub/index");
- }
- }
- }
这里给大家写了一个简单的RBAC类,仅供大家学习参考此思想,如有问题可以跟帖回复....
欢迎拍砖哈......
更多给力文章,请挪步:
【捷哥浅谈PHP】第一弹---php位运算符”|”和逻辑运算符”||”遇到的问题
【捷哥浅谈PHP】第二弹---经典算法的运用(冒泡排序和快速排序)
【捷哥浅谈PHP】第三弹---使用二分查找法查找数组中的元素位置
【捷哥浅谈PHP】第四弹---递归函数
【捷哥浅谈PHP】第五弹 --- 分页之九阳神功
【捷哥浅谈PHP】第六弹 ---- 使用for循环输出九九乘法表
原文地址:http://bbs.lampbrother.net/read-htm-tid-118412.html
0
上一篇:【捷哥浅谈PHP】第七弹 ---- 基于角色的访问控制RBAC
下一篇:【大官人High帖】为粮票,大官人不再发激情照。今天是:生成字符串
相关热门文章
- IP Sec VPN与NAT破镜重圆
- 网站导航
- GoAgent图文设置教程
- UT2.0正式版下载
- tomcat6.0配置(含配置视频下载...
- 大家都是用什么来管理hadoop集...
- 网站被人挂了吗,添加了些程序...
- Nginx如何保证不走宕机的那个...
- 大家谈谈MYSQL客户端和服务器...
- 以下代码运行后为何会输出5?...
给主人留下些什么吧!~~
评论热议
- 【捷哥浅谈PHP】第七弹 ---- 基于角色的访问控制RBAC
- 【捷哥浅谈PHP】第七弹 ---- 基于角色的访问控制RBAC
- 基于角色的访问控制-rbac-yii
- RBAC基于角色的访问控制 thinkphp
- RBAC(基于角色的访问控制)的实现
- 基于角色的访问控制RBAC的mysql表设计
- 基于角色的访问控制(RBAC)介绍
- RBAC(Role-Based Access Control)基于角色的访问控制
- RBAC(基于角色的访问控制)扫盲贴
- 基于角色的访问控制 (RBAC)- 常见问题
- YII framework下基于角色的访问控制(RBAC)
- RBAC(Role-Based Access Control)基于角色的访问控制
- YII framework下基于角色的访问控制(RBAC)
- 基于角色的访问控制:RBAC模型笔记
- 基于角色的访问控制(RBAC)介绍
- 基于角色的访问控制 (RBAC)权限管理
- RBAC(用户权限管理) 基于角色的访问控制
- RBAC基于角色的访问控制模型(权限管理)
- 初级阶段总结
- $学习帖="非文学帖";
- 恼人的春天
- 第一个项目快开始了,本人把PHP基础的应用总结了一部分,有需要的同学可以看看
- 【捷哥浅谈PHP】第七弹 ---- 基于角色的访问控制RBAC
- 【捷哥浅谈PHP】第七弹 ---- 基于角色的访问控制RBAC
- PostThreadMessage()
- 【大官人High帖】为粮票,大官人不再发激情照。今天是:生成字符串
- 乱世群雄,V5七师---“first blood”
- 肉体已逝,精神永存。---第一期项目感受
- 肉体已逝,精神永存。---第一期项目感受
- 第一次完成千万级数据的网站 发帖留念
- MonoRail学习笔记系列文章
- 兄弟连第一届非官方感恩父母活动
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
一旦一夕
我有一个拼夕夕系统
大唐我有拼夕夕系统
将门侯妻倾城一品嫡女慕云夕
大唐我有个拼夕夕系统
一夜钟禽
第一狂妃夜轻歌
一夜锁情总裁先生请温柔
一遇夜白误终生
一夜回到改开前
第一狂妃夜轻歌大结局
一夜
第一狂妃夜轻歌全文免
一夜惊喜
第一狂妃夜轻歌全文免费阅读
一夜惊喜总裁爹地欺上门
七天七夜各种姿势来一遍
一夜甜蜜总裁宠妻入骨
第一狂妃夜轻歌全文阅读
苍泽萝泷一日两夜播放
第一狂妃废材三小夜轻歌
第一福利夜趣
第一夜的蔷薇
一夜成名
北京一夜
天天夜日天天第一页
一夜疯狂
第一夜蔷薇
一夜成名红枣
夜帝第一狂妃
陈七夜第一章仙帝归来
仅此一夜
天阶夜凉如水下一句
一夜危情
一遇夜白误终身
亚洲第一夜
一夜之情
男人一夜几次正常
一夜弃妃替身侍婢魅君心
一夜风情
鼻头长痘一夜消除