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 ...
随机推荐
- 生成shadow中hash字串
[root@master base]# openssl passwd -1 -salt 123Password: $1$123$2rm.J6pr3p.rmj6YoKSQ8.[root@master b ...
- 前端利器,如何使用fiddle拦截在线css进行先下调试
fiddle的功能相当的强悍,用户也非常广,不过今天我就教大家用fiddle进行前端调试. 首先下载软件fiddle,点击对应的版本下载安装. 安装成功后打开看到右侧的导航栏: 点击AutoRespo ...
- wordpress一些常用代码
显示最新文章 <div id="newpost"> <h2> 最新文章</h2> <?php $previous_posts = get_ ...
- netbeans ide怎么添加yii代码提示
菜单栏选择工具->选项->php界面里的全局包含路径中选择framework这个文件夹就可以了
- 整体刷新和局部刷新frameset窗口(转)
在项目中,经常会遇到页面分割,最常见的系统或网站的主界面.主页面分为,上面系统简介.下面作者简介.左边系统功能菜单.右边则是菜单真正展示的界面. 遇到这种这种分割页面,大家 ...
- eclipsecpp从可执行程序员中导入源代码并调试
如果寻找跨平台IDE及调试环境,那eclipse是最佳选择了,因为它有一项超强功能:可以从可执行程序员导入源代码并调试程序,这种特性是非常适合自定义MakeFile项目,不需要改变项目现有结果,即可自 ...
- SonarQube代码质量管理平台工具
1.Sonar轮廓介绍 Sonar (SonarQube)是一个开源平台,用于管理源代码的质量.Sonar 不只是一个质量数据报告工具,更是代码质量管理平台.支持的语言包括:Java.PHP.C#.C ...
- linux之SQL语句简明教程---Alias
接下来,我们讨论 alias (别名) 在 SQL 上的用处.最常用到的别名有两种: 栏位别名及表格别名. 简单地来说,栏位别名的目的是为了让 SQL 产生的结果易读.在之前的例子中,每当我们有营业额 ...
- C#字典Dictionary排序(顺序、倒序)
这里是针对.NET版本过低的排序方式,没怎么用过,记录一下: 一.创建字典Dictionary 对象 假如 Dictionary 中保存的是一个网站页面流量,key 是网页名称,值value对应的是网 ...
- Avoid The Lakes
Avoid The Lakes Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) To ...