thinkPHP框架RBAC实现原理分析


Posted in PHP onFebruary 01, 2019

本文实例讲述了thinkPHP框架RBAC实现原理。分享给大家供大家参考,具体如下:

RBAC就是:Role Based Access Controller,基于角色(role)的权限(Access)管理,这里简单介绍一下他的原理与实现方式之一。

Part 1 数据库设计

首先最基本的组成有:用户(admin),角色(role),具体权限(auth),这三者之间的关系是这样的:一个用户只拥有一种角色,一种角色下拥有多个权限,一个权限也会同时被多个角色拥有,也就是说admin表和role表是一对一关系,role和auth表是多对多关系,本来符合范式设计要求的情况应该是需要一张关联表的,但是这里为了简单,就只把role拥有的auth写成一个字段auth_id_lst。所以具体的表设计就是:

admin

  • admin_id
  • admin_name
  • role_id (foreign_key)

role

  • role_id
  • role_name
  • auth_id_lst

auth

  • auth_id
  • auth_name
  • auth_pid

为了更直接的理解,这里放几个每张表的具体记录:

auth

auth_id auth_name auth_pid
1 供应商管理 0
2 供应商添加 1
3 供应商修改 1
4 商品管理 0
5 商品下架 4
6 顾客管理 0

role

role_id role_name auth_id_lst
1 物流部门经理 1,2,3
2 销售部门经理 4,5
3 公关部门经理 6

admin

admin_id admin_name role_id
1 张三 1
2 李四 2
3 王五 3

这样就可以保存住具体的用户所拥有的具体权限了,而其中为了能更好的管理具体auth,同时也为了更好的理解,所以加入了role表进行补充,如果做一个类似的话,更像下面的形式:

  • admin:具体人员
  • role:部门
  • auth:具体所需要的权限

同一个部门的人,所需要的权限基本是相同的,所以可以使用一个role进行统一管理。

Part 2 代码实现

上面只是简单做一个介绍,这一部分开始将介绍具体的实施方案,来自于一个带我的大哥。看懂下面的部分你需要具备的知识点有:

  • thinkphp的基础知识
  • session的用法

这个使用的场景是一个后台管理系统,针对不同role开放不同的Controller(控制器)和Action(方法),所以auth表具体结构如下:

admin

  • auth_id
  • auth_name
  • auth_c 保存控制器名
  • auth_a 保存方法名
  • auth_pid 权限之间存在分类情况,使用该字段进行保存

接下来就是具体的操作步骤了:

1.1 新建Controller类

在thinkphp中每个Controller都会继承一个thinkphp下的Think\Controller,这个时候可以新建一个Controller,之后让所有的Controller都继承这个新建的类,这样所有进行的操作都要先经过这个新建控制器的筛选。

下面是这个新建类的部分内容:

<?php
namespace Admin\Controller;
use Think\Controller;
class FatherController extends Controller{
  // 构造函数
  public function __construct(){
    // 实例化父类构造函数
    parent::__construct();
    // session('admin_id')会在后面的验证成功后被保存
    // session()中的?表示判断
    fi(!session('?admin_id')){
      $this->error('必须登录后才可以执行操作',U('Back/login'));
    }
    // 后面还有内容,这里先到这里
  }
}
?>

1.2 跳转到登录页面

1.1中跳转到一个登录的页面,在这个登录页面中输入用户名、密码、验证码之后,就可以调用专门Model类来进行验证了。这里就细讲了,这里讲解一下具体步骤:

  • 在BackController的login方法中实例化AdminModel类
  • 在AdminModel类中设置自动验证和自动完成,保证用户名和密码都经过验证
  • 如果用户名和密码都正确,则将admin_id保存在session中,并从role表中读取该用户的role,与auth_id_lst,同样保存在session中。这里做一下总结:

session('admin_id') 登录者的id

session('user_name') 登录者注册名

session('auth') 登录者所拥有的role中的auth_id_lst中对应auth表的具体值,格式为 Controller/Action
session('menu') 登录者所能操作的具体的权限信息

1.3 回到最初新建的Controller类

<?php
namespace Admin\Controller;
use Think\Controller;
class FatherController extends Controller{
  // 构造函数
  public function __construct(){
    // 实例化父类构造函数
    parent::__construct();
    // session('admin_id')会在后面的验证成功后被保存
    // session()中的?表示判断
    fi(!session('?admin_id')){
      $this->error('必须登录后才可以执行操作',U('Back/login'));
    }
    // 这里是后面新建的内容
    // CONTROLLER_NAME 当前调用的控制器名,think的变量
    // ACTION_NAME 与CONTROLLER_NAME一样,表示当前调用的控制器下的方法
    $currentMethod=CONTROLLER_NAME.'/'.ACTION_NAME;
    // 上面其实是thinkphp一般的pathinfo模式的url格式
    // Index随便调用,其实就是主页,在主页有其他设置,用于展现其所拥有的权限,这个后面再看
    if(CONTROLLER_NAME=='Index'){
      return true;
    }
    // 读取用户所拥有的所有权限,已经将字符串解析成数组形式了
    $allowMethod=session('auth_id_lst');
    // *表示超级用户,拥有所有权限,如果用户请求超越自己权限的操作,则会显示错误提示页面
    if($allowMethod!='*' && !in_array($currentMethod, $allowMethod)){
      $this->error('越权操作',U('Index/index'));
    }
  }
}
?>

1.4 主页显示内容

主页是使用thinkphp的内置标签自动生成的,所以只要把握好输出的内容,就可以限制住给于用户的操作权限,上面说过,其中赋予用户的操作权限都是保存在session('menu')中,所以只要在内置标签中调用这个值进行显示就可以了,具体内容就是这样。

讲的很烂我知道,毕竟只花了半个小时看其中的具体内容,之后可能会尝试自己写写看吧,那时候再说吧。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
php 在文件指定行插入数据的代码
May 08 PHP
php实现用户在线时间统计详解
Oct 08 PHP
分享下PHP register_globals 值为on与off的理解
Sep 26 PHP
php 无限级分类,超级简单的无限级分类,支持输出树状图
Jun 29 PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
Jul 08 PHP
PHP读取CURL模拟登录时生成Cookie文件的方法
Nov 04 PHP
DOM基础及php读取xml内容操作的方法
Jan 23 PHP
PHP判断上传文件类型的解决办法
Oct 20 PHP
微信获取用户地理位置信息的原理与步骤
Nov 12 PHP
php中时间函数date及常用的时间计算
May 12 PHP
php 读取文件夹下所有图片、文件的实例
Oct 17 PHP
PHP crypt()函数的用法讲解
Feb 15 PHP
PHP PDOStatement::fetchColumn讲解
Jan 31 #PHP
PHP PDOStatement::fetchAll讲解
Jan 31 #PHP
PHP PDOStatement::fetch讲解
Jan 31 #PHP
PHP PDOStatement::execute讲解
Jan 31 #PHP
PHP PDOStatement::errorInfo讲解
Jan 31 #PHP
PHP PDOStatement::errorCode讲解
Jan 31 #PHP
PHP PDOStatement::columnCount讲解
Jan 30 #PHP
You might like
关于Appserv无法打开localhost问题的解决方法
2009/10/16 PHP
PHP基于IMAP收取邮件的方法示例
2017/08/07 PHP
JS启动应用程序的一个简单例子
2008/05/11 Javascript
一些有用的JavaScript和jQuery的片段分享
2011/08/23 Javascript
javascript同页面多次调用弹出层具体实例代码
2013/08/16 Javascript
JavaScript中Number.MAX_VALUE属性的使用方法
2015/06/04 Javascript
js智能获取浏览器版本UA信息的方法
2016/08/08 Javascript
jQuery 移动端拖拽(模块化开发,触摸事件,webpack)
2016/10/28 Javascript
微信小程序 switch组件详解及简单实例
2017/01/10 Javascript
canvas绘制万花筒效果(代码分享)
2017/01/20 Javascript
js中new一个对象的过程
2017/02/20 Javascript
基于Vue实现timepicker
2017/04/25 Javascript
js实现拖拽上传图片功能
2017/08/01 Javascript
vue2.0 和 animate.css的结合使用
2017/12/12 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
详解Webpack loader 之 file-loader
2018/11/07 Javascript
three.js搭建室内场景教程
2018/12/30 Javascript
JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落效果
2020/03/17 Javascript
Vue 401配合Vuex防止多次弹框的案例
2020/11/11 Javascript
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
2021/01/05 Vue.js
[42:27]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第三局
2016/03/05 DOTA
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python简单爬虫导出CSV文件的实例讲解
2018/07/06 Python
解决在pycharm中显示额外的 figure 窗口问题
2019/01/15 Python
python实现合并两个排序的链表
2019/03/03 Python
解决python运行效率不高的问题
2020/07/20 Python
解决python打开https出现certificate verify failed的问题
2020/09/03 Python
如何使用python自带IDLE的几种方法
2020/10/10 Python
详解CSS3选择器的使用方法汇总
2015/11/24 HTML / CSS
美国知名奢侈美容品牌零售商:Cos Bar
2017/04/21 全球购物
美国最大的半成品净菜电商:Blue Apron(蓝围裙)
2018/04/27 全球购物
2014年最新学习全国两会精神心得
2014/03/17 职场文书
群众路线查摆问题整改措施思想汇报
2014/10/10 职场文书
论群众路线学习心得体会
2014/10/31 职场文书
MySQL的Query Cache图文详解
2021/07/01 MySQL
Android Canvas绘制文字横纵向对齐
2022/06/05 Java/Android