thinkPHP3.2使用RBAC实现权限管理的实现


Posted in PHP onAugust 27, 2019

在thinkphp3.2中自己集成了RBAC来实现权限管理,RBAC实现类在项目中地址为:ThinkPHP/Librar/Org/Util/Rbac.class.php,其中集成了我们所需的权限管理操作

一:表设计

在thinkPHP的Rbac的的Rbac.class.php文件中一共提供了4张表,还有一张用户表需要你自己去建

如下是我所建的和权限相关的sql

其中的wj_为表前缀,改成你项目中的表前缀

1:权限表:

CREATE TABLE IF NOT EXISTS `wj_access` (
 `role_id` SMALLINT(6) UNSIGNED NOT NULL COMMENT '角色ID',
 `node_id` SMALLINT(6) UNSIGNED NOT NULL COMMENT '节点ID',
 `level` TINYINT(1) NOT NULL COMMENT '深度',
 `module` VARCHAR(50) DEFAULT NULL COMMENT '模块',
 KEY `groupId` (`role_id`),
 KEY `nodeId` (`node_id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT='权限表';

2:节点表:

CREATE TABLE IF NOT EXISTS `wj_node` (
 `id` SMALLINT(6) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '节点ID',
 `name` VARCHAR(20) NOT NULL COMMENT '节点名称',
 `title` VARCHAR(50) DEFAULT NULL COMMENT '节点标题',
 `status` TINYINT(1) DEFAULT '0' COMMENT '状态 0禁用 1启用',
 `remark` VARCHAR(255) DEFAULT NULL COMMENT '描述',
 `sort` SMALLINT(6) UNSIGNED DEFAULT NULL COMMENT '排序',
 `pid` SMALLINT(6) UNSIGNED NOT NULL COMMENT '父级节点',
 `level` TINYINT(1) UNSIGNED NOT NULL COMMENT '深度',
 PRIMARY KEY (`id`),
 KEY `level` (`level`),
 KEY `pid` (`pid`),
 KEY `status` (`status`),
 KEY `name` (`name`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT='节点表';

3:用户角色表:

CREATE TABLE IF NOT EXISTS `wj_role` (
 `id` SMALLINT(6) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '角色ID',
 `name` VARCHAR(20) NOT NULL COMMENT '角色名称',
 `pid` SMALLINT(6) DEFAULT NULL '父级ID',
 `status` TINYINT(1) UNSIGNED DEFAULT NULL COMMENT '状态 0禁用 1启用',
 `remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
 PRIMARY KEY (`id`),
 KEY `pid` (`pid`),
 KEY `status` (`status`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT='用户角色表';

4:用户角色关联表:

CREATE TABLE IF NOT EXISTS `wj_role_user` (
 `role_id` MEDIUMINT(9) UNSIGNED DEFAULT NULL COMMENT '角色ID',
 `user_id` CHAR(32) DEFAULT NULL COMMENT '用户ID',
 KEY `group_id` (`role_id`),
 KEY `user_id` (`user_id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT='用户角色关联表';

5:用户表:

CREATE TABLE IF NOT EXISTS `wj_user` (
 `user_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户ID',
 `username` VARCHAR(50) NOT NULL COMMENT '用户名',
 `password` VARCHAR(100) NOT NULL COMMENT '密码',
 `create_time` INT(10) DEFAULT NULL COMMENT '创建时间',
 `update_time` INT(10) DEFAULT NULL COMMENT '更新时间',
 `status` INT(1) DEFAULT NULL COMMENT '状态 0禁用 1启用',
 PRIMARY KEY (`user_id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT='用户表';

二:关于权限操作的常用配置:

你可以在config.php文件的数组中增加:

// 加载扩展配置文件
'LOAD_EXT_CONFIG' => 'user',

这样的话我们就可以将我们的所有权限配置放置在config.php同级的user.php文件中,user.php文件配置如下:

<?php
/**
 * 用户权限配置文件
 */
return array(
  // 是否需要认证
  'USER_AUTH_ON' => true,
  // 认证类型 1 登录认证 2 实时认证
  'USER_AUTH_TYPE' => 1,
  // 后台用户认证SESSION标记
  'USER_AUTH_KEY' => 'wjAuthId',
  // 默认认证网关
  'USER_AUTH_GATEWAY' => '?m=Admin&c=Login&a=index',
  // RBAC_DB_DSN 数据库连接DSN
  // 角色表名称,C('DB_PREFIX')表示前缀
  'RBAC_ROLE_TABLE' => C('DB_PREFIX') . 'role',
  // 用户角色关联表名称
  'RBAC_USER_TABLE' => C('DB_PREFIX') . 'role_user',
  // 权限表名称
  'RBAC_ACCESS_TABLE' => C('DB_PREFIX') . 'access',
  // 节点表名称
  'RBAC_NODE_TABLE' => C('DB_PREFIX') . 'node',
  // 默认验证数据表模型
  'USER_AUTH_MODEL' => 'User',
  // 超级管理员的SESSION标记
  'ADMIN_AUTH_KEY' => 'wjAdministrator',
  // 默认需要认证模块
  'REQUIRE_AUTH_MODULE' => '',
  // 默认需要认证操作
  'REQUIRE_AUTH_ACTION' => '',
  // 默认无需认证模块
  'NOT_AUTH_MODULE' => 'Public',
  // 默认无需认证操作
  'NOT_AUTH_ACTION' => '',
  // 是否开启游客授权访问
  'GUEST_AUTH_ON' => false,
  // 游客的用户ID
  'GUEST_AUTH_ID' => 0,
  // 后台用户名的SESSION标记
  'BACK_LOGIN_NAME' => 'loginBackName',
  // 后台角色的SESSION标记
  'BACK_USER_ROLE' => 'bakcUserRole',
  // 后台角色ID的SESSION标记
  'BACK_ROLE_ID' => 'backRoleId',
  // 后台用户登录时间的SESSION标记
  'BACK_ONLINE_TIME' => 'backOnlineTime',
  // 后台在线间隔时间,以分钟为单位
  'ONLINE_INTERVAL' => 180,
  //退出登录的URL
  'LOGOUT_URL' => '/test',
);

三:关于权限操作的常用方法:

1:Rbac::saveAccessList($authId=null);

缓存权限列表,在这个方法可以传递空值的前提是:你在用户登录操作的时候要在 $_SESSION[C('USER_AUTH_KEY')] 中把用户的id保存下来,然后这里会将用户所对应的角色拥有的权限都保存在$_SESSION['_ACCESS_LIST']中

2:Rbac::checkAccess()

判断用户访问的模块和方法是否需要权限认证

3:Rbac::AccessDecision()

断用户是否有访问权限的,即检测当前项目模块操作 是否在$_SESSION['_ACCESS_LIST']数组中,也就是说 在 $_SESSION['_ACCESS_LIST'] 数组中$_SESSION'_ACCESS_LIST''当前控制器'是否存在。如果存在表示有权限 否则返回flase

4:Rbac::checkLogin();

判断用户是否登录,如果未登录则跳转到指定路径

5:Rbac::getAccessList($authId)

通过查询数据库 返回权限列表 $_SESSION['_ACCESS_LIST']的值

6:Rbac::authenticate($map, $model='')

传入查询用户的条件和用户表的MODEL 返回数组包含用户的信息,如果不传model值的话使用配置项中的USER_AUTH_MODEL

四:权限管理简单实现实例:

1:登录:

//获取传递的用户名和密码
$username = I('post.username');
$password = I('post.password');
//生成认证条件
$map = array();
$map['username'] = $username;
$map['status'] = array('eq', 1);
//判断是否存在此用户
$authInfo = Rbac::authenticate($map);
if (!$authInfo) {
  $this->error('账号不存在');
}
if ($authInfo['password'] != md5($password)) {
  $this->error('密码错误');
}
$user_id = $authInfo['user_id'];
$role_user = new Model();
$role = $role_user->Table(C("RBAC_USER_TABLE"))->alias("user")->where("user_id=" . $user_id)->join(C("RBAC_ROLE_TABLE") . " as role ON role.id=user.role_id")->field("id,name")->find();
if (empty($role)) {
  $this->error('此用户无对应的角色,无法登录');
}
//后台角色ID的SESSION标记
session(C('BACK_ROLE_ID'), $role['id']);
//后台角色的SESSION标记
session(C('BACK_USER_ROLE'), $role['name']);
//后台用户认证SESSION标记
session(C('USER_AUTH_KEY'), $authInfo['user_id']);
//后台用户名的SESSION标记
session(C('BACK_LOGIN_NAME'), $authInfo['username']);
//后台用户登录时间的SESSION标记
session(C('BACK_ONLINE_TIME'), time());
//判断用户角色是否为超级管理员
if ($role['id'] == '1') {
  //超级管理员将超级管理员的SESSION标记设置为true
  session(C('ADMIN_AUTH_KEY'), true);
}
// 缓存访问权限
Rbac::saveAccessList();
$this->success('登录成功', U('Index/index'));

2:登录成功后的权限校验:

//验证是否登录
Rbac::checkLogin();
// 用户权限检查
if (Rbac::checkAccess() && !Rbac::AccessDecision()) {
  // 没有权限 清除登录session 并抛出错误
  if (C('RBAC_ERROR_PAGE')) {
    // 定义权限错误页面
    redirect(C('RBAC_ERROR_PAGE'));
  } else {
    if (C('GUEST_AUTH_ON')) {
      //开启游客访问
    }
    // 提示错误信息
    $this->error(L('_VALID_ACCESS_'));
  }
}
//自动退出功能,判断后台用户登录时间的SESSION标记是否超时
if (session(C('BACK_ONLINE_TIME')) + C('ONLINE_INTERVAL') * 60 < time()) {
  if (session('?' . C('USER_AUTH_KEY'))) {
    session('[destroy]');
    if (isset($_COOKIE[session_name()])) {
      setcookie(session_name(), '', time() - 3600, '/');
    }
    session_destroy();
  }
  $this->error('超时请重新登录', U('Login/index'));
} else {
  session(C('BACK_ONLINE_TIME'), time());
}

根据如上就可以实现用户角色的权限管理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP一些有意思的小区别
Dec 06 PHP
php 远程关机操作的代码
Dec 05 PHP
php zend 相对路径问题
Jan 12 PHP
PHP缓存技术的使用说明
Aug 06 PHP
解析mysql left( right ) join使用on与where筛选的差异
Jun 18 PHP
Yii框架调试心得--在页面输出执行sql语句
Dec 25 PHP
php实现将wav文件转换成图像文件并在页面中显示的方法
Apr 21 PHP
Windows 下安装 swoole 图文教程(php)
Jun 05 PHP
php基于协程实现异步的方法分析
Jul 17 PHP
php实现JWT(json web token)鉴权实例详解
Nov 05 PHP
PHP 计算至少是其他数字两倍的最大数的实现代码
May 26 PHP
php判断IP地址是否在多个IP段内
Aug 18 PHP
PHP如何将图片文件上传到另外一台服务器上
Aug 26 #PHP
PHP命名空间与自动加载机制的基础介绍
Aug 25 #PHP
php的命名空间与自动加载实现方法
Aug 25 #PHP
PHP7数组的底层实现示例
Aug 25 #PHP
PHP实现cookie跨域session共享的方法分析
Aug 23 #PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
Aug 23 #PHP
php中错误处理操作实例分析
Aug 23 #PHP
You might like
在JavaScript中调用php程序
2009/03/09 PHP
php PDO属性设置与操作方法分析
2018/12/27 PHP
关于javascript function对象那些迷惑分析
2011/10/24 Javascript
JS控件的生命周期介绍
2012/10/22 Javascript
js中符号转意问题示例探讨
2013/08/19 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
2013/12/16 Javascript
jQuery修改class属性和CSS样式整理
2015/01/30 Javascript
javascript 使用for循环时该注意的问题-附问题总结
2015/08/19 Javascript
15个常用的jquery代码片段
2015/12/19 Javascript
jQuery查找节点并获取节点属性的方法
2016/09/09 Javascript
jQuery实现遍历复选框的方法示例
2017/03/06 Javascript
JS处理一些简单计算题
2018/02/24 Javascript
vue初始化动画加载的实例
2018/09/01 Javascript
详解JavaScript栈内存与堆内存
2019/04/04 Javascript
Python对象体系深入分析
2014/10/28 Python
Python中的模块导入和读取键盘输入的方法
2015/10/16 Python
Python3中的真除和Floor除法用法分析
2016/03/16 Python
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
2016/12/15 Python
使用pip安装python库的多种方式
2019/07/31 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
python 输出列表元素实例(以空格/逗号为分隔符)
2019/12/25 Python
英国领先的运动营养品牌:Protein Dynamix
2018/01/02 全球购物
领先的英国注册在线药房 :Simply Meds Online
2019/03/28 全球购物
编写strcpy函数
2014/06/24 面试题
Java基础面试题
2014/07/19 面试题
学子宴答谢词
2014/01/25 职场文书
运动会通讯稿400字
2014/01/28 职场文书
模具设计与制造专业自荐书
2014/07/01 职场文书
公司租房协议书
2014/10/14 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
小学语文教师年度考核个人总结
2015/02/05 职场文书
留学推荐信怎么写
2015/03/26 职场文书
公司市场部岗位职责
2015/04/15 职场文书
二审代理词范文
2015/05/25 职场文书
MySql存储过程之逻辑判断和条件控制
2021/05/26 MySQL
Java 超详细讲解hashCode方法
2022/04/07 Java/Android