ThinkPHP框架下基于RBAC的权限控制模式详解
这几天因为要做一个项目,需要可以对Web应用中通用功能进行封装,其中一个很重要的涉及到了对用户、角色和权限部分的灵活管理。所以基于TP框架自己封装了一个对操作权限和菜单权限进行灵活配置的可控制模式。
RBAC角色权限分配模式大家或许都不陌生,其重要的访问控制原理就是将权限基于角色进行动态分配,在一个工作模式中,每个人都被分配了不同的角色,因为每个人角色的不同所以每个人负责的事情也不同。最简单的举一个例子来说吧,就一个大学而言,一个大学分为校长、某个学院的院长、某个系的系主任,他们每个人都有不同的角色,校长要做可能就是宏观把控整个学校的大方向,院长就是对自己这个学院负责,系主任呢就是应该对自己系里面的各种具体的事情进行处理和监督。从例子中,大家可能也已经看出来了,在整个的工作组织中,由上而下分为了很多不同的角色,而且每个不同角色的人承担的责任也不同,所以我们在我们的灵活可配置的控制模式中应该做到对不同级别、不同角色的用户的操作权限进行动态配置,这样就不用我们写大量的重复代码,节省了我们大量的时间。
其实,在TP框架中也自带了一个角色权限分配的封装代码,可是我自己不太想用它的,所以自己去封装吧。
在RBAC的权限分配模式中,我们所有的权限都是基于角色,所以我们应该有一个非常重要的可以左右联系的表->role表(角色表)。现在我们有了角色表,可是我们最终的服务对象还是我们的用户,真正使角色有意义的是用户,因为是某个用户具有某个角色,所以我们还应该有一个基本的用户表->user表(用户表)。现在角色左边的用户表有了,那么还缺少一个什么呢?那就是我们的权限表,因为我们不同的操作对应的是是否具有该操作的执行权限,所以我们还应该有一个基本的权限表->access表(权限表)。现在有了这些表,我们还应该将这些表联系起来,那就是用户角色表->user_role表和角色权限表->role_access表。上面这五个表就是RBAC模式中最基本的5张表。但是现在我还想能够将菜单也做成灵活可定制的,所以还需要有一个menu表。其实到了这里,就是出现一个分歧,那就是我们菜单和角色的关联,现在有两个途径,一个就是将菜单也当成用户的操作权限,将菜单作为一个权限放在权限表中去为角色分配。另外一个就是在扩展一个角色菜单表role_menu表,我们将菜单级别的权限配置专门进行管理,做菜单的灵活配置。
所有的表有了,接下来就是做到如何才能对操作权限和菜单权限进行控制呢?这就需要针对不同的底层框架去实现了,在TP框架中,自己一开始想说去用行为类实现。我想专门去实现了一个检查权限的行为类,在每次执行操作的时候都去检查是否有该操作权限,若没有则给出提示,并停止执行代码。虽然整体的设计没有错,可是自己在实现时,发现我们每次都要去用B方法调用该行为类,让它去执行run()方法,这样显然不方便。后来自己好好想了想,发现刚才自己的想法太蠢了,其实自己完全没有必要去用行为类做,仅仅是一个控制器就完全可以实现。
具体的做法是这样,我封装了一个基类的AdminController(因为主要是针对后台的),让所有后台应用的控制器都去继承自AdminController,在每个控制器的构造函数中都去继承AdminController的构造函数,这样我每次的请求在执行时都会去初始化AdminController中的构造函数,然后我在基类的构造函数中去截获当前执行操作的控制器和对应的方法,然后去对比操作权限,如果存在则“放行”,如果没有,那就不好意思,给出一个提示哈。
菜单也是相似的操作。不过我在控制器中设置了对admin管理员的自动过滤,让admin自动拥有所有的菜单和权限。
经过以上的操作,我们就实现了对权限的控制,并且是对菜单级别和按钮级别均有控制。
好了,接下来奉上在权限判断部分的代码,供大家参考。
public function __construct(){
parent::__construct();
if(session("?loginuser")){ //表示当前人已经登录,则我们应该获取
$loginuser=session("loginuser"); //获取当前登录人的session值
if($loginuser!="admin"){ //只有在当前登录人不是admin的时候,我们才需要去获取当前人执行的请求方法,然后进行权限对比
$con_name=CONTROLLER_NAME;
$fun_name=ACTION_NAME;
$url=$con_name."/".$fun_name;
$access_urls=session("access_urls"); //将所有目前session中的权限获取出来 //echo "<script>alert('".$url."')</script>";
if($fun_name!="ajaxIndex"){ //echo "<script>alert('".$url."')</script>";
if($url=="Index/index"||$url=="Index/head"||$url=="Index/left"||$url=="Index/right"){ //我们默认给出显示首页的三个方法的权限 }
else{
$is_have="error";
foreach ($access_urls as $key => $value) {
# code...
if(in_array($url, $value)){
$is_have="ok";
break;
}
} if($is_have=="error"){ //若最终为error,则表示当前没有该权限
echo "<script>alert('您不具备该权限!')</script>";
die();
}
}
}
} }
else{
$this->redirect("Login/showLogin");
}
好了,上述部分就是一个简单的权限控制模式,并且是到按钮级别哟。
在补充一句吧,上述只是基于TP框架的封装。其它具体框架可以具体操作,比如Laravel框架,在Laravel中新推出了一个叫中间件的东西,在这个中间件中所有的操作都会经过这个中间件,所以,我们就可以在这个中间件中做非常多的事情啦。
好了,到此结束,也写上那句话吧:此文属于博主原创,如果转载,请标明出处哟。
ThinkPHP框架下基于RBAC的权限控制模式详解的更多相关文章
- 两种RBAC权限控制模型详解
序言 由于最近一直卡在权限控制这个坎上,原来设计的比较简单的权限控制思路已经无法满足比较复杂一些的场景,因此一直在探索一种在大部分场景下比较通用的权限模型. 首先,这里说明一下两种RBAC权限模型分别 ...
- php_ThinkPHP的RBAC(基于角色权限控制)详解
一.什么是RBAC 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注. 在RBAC中,权限与角色相关联,用户通 ...
- 基于RBAC的权限控制浅析(结合Spring Security)
嗯,昨天面试让讲我的项目,让我讲讲项目里权限控制那一块的,讲的很烂.所以整理一下. 按照面试官的提问流程来讲: 一.RBAC是个啥东西了? RBAC(Role-Based Access Control ...
- webapi框架搭建-安全机制(四)-可配置的基于角色的权限控制
webapi框架搭建系列博客 在上一篇的webapi框架搭建-安全机制(三)-简单的基于角色的权限控制,某个角色拥有哪些接口的权限是用硬编码的方式写在接口上的,如RBAuthorize(Roles = ...
- webapi框架搭建-安全机制(三)-简单的基于角色的权限控制
webapi框架搭建系列博客 上一篇已经完成了“身份验证”,如果只是想简单的实现基于角色的权限管理,我们基本上不用写代码,微软已经提供了authorize特性,直接用就行. Authorize特性的使 ...
- 图文详解基于角色的权限控制模型RBAC
我们开发一个系统,必然面临权限控制的问题,即不同的用户具有不同的访问.操作.数据权限.形成理论的权限控制模型有:自主访问控制(DAC: Discretionary Access Control).强制 ...
- RBAC: K8s基于角色的权限控制
文章目录 RBAC: K8s基于角色的权限控制 ServiceAccount.Role.RoleBinding Step 1:创建一个ServiceAccount,指定namespace Step 2 ...
- .NET环境下基于RBAC的访问控制
.NET环境下基于RBAC的访问控制 Access Control of Application Based on RBAC model in .NET Environment 摘 要:本文从目前信息 ...
- Spring Security实现基于RBAC的权限表达式动态访问控制
昨天有个粉丝加了我,问我如何实现类似shiro的资源权限表达式的访问控制.我以前有一个小框架用的就是shiro,权限控制就用了资源权限表达式,所以这个东西对我不陌生,但是在Spring Securit ...
随机推荐
- Java IO之序列化
序列化机制是Java语言内建的一种对象持久化方式,可以很容易的在JVM中的活动对象和字节数组之间转换.它的一个重要用途就是远程方法调用的时候,用来对开发人员屏蔽底层实现细节(远端的开发人员不知道这个对 ...
- 寒冰王座(hd1248)
寒冰王座 Problem Description 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店 ...
- Echart 官网给的一个直观的事例
附录:一个直观的事例 查看更多实例 example,或者使用这个demo 或 ECharts单一文件引入作为你的模板 // 图表实例化------------------ // srcipt标签式引入 ...
- grok 正则解析日志例子<1>
<pre name="code" class="html">下面是日志的样子 55.3.244.1 GET /index.html 15824 0. ...
- 2014第6周五JS调试
今天才发现chrome调试前端尤其是JS真是很方便,难怪之前公司几个前端高手都用chrome的开发者工具来调试.把今天知道的chrome调试方法收集整理一下,在今后的开发调试中都可能会用到: Prof ...
- #include <bitset>
1 none();测试是否有越位 2 reset();全部清零 3 set(7, 0);把第7个字符改成0,操作二进制位 4 to_string();转换为字符串 5 to_ulong();转换为无符 ...
- Iterator(迭代器模式)--(超市管理者)
这个Iterator就是收银台干的活. package patterns.actions.iterator; public interface IteratorList { boolean isEmp ...
- Objective-C——判断对象等同性
无论我们使用什么语言,总是会出现需要判断两个对象是否相等的情况,OC当然也不例外.首先看一段代码: NSString *str1 = [[NSString alloc] initWithCString ...
- 性能强悍的开源关系数据库PostgreSQL
性能强悍的开源关系数据库PostgreSQL
- JS实现简单倒计时
/*倒计时*/ lcf.downTime = function (endTime,obj,callback){ /*基本判断*/ if(!endTime || typeof endTime !== & ...