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 相关文章推荐
BBS(php &amp; mysql)完整版(五)
Oct 09 PHP
PHP 模拟$_PUT实现代码
Mar 15 PHP
php连接mssql的一些相关经验及注意事项
Feb 05 PHP
PHP屏蔽过滤指定关键字的方法
Nov 03 PHP
CodeIgniter记录错误日志的方法全面总结
May 17 PHP
ThinkPHP实现静态缓存和动态缓存示例代码
May 02 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
Jun 13 PHP
PHP asXML()函数讲解
Feb 03 PHP
PHP中str_split()函数的用法讲解
Apr 11 PHP
laravel 输出最后执行sql 附:whereIn的使用方法
Oct 10 PHP
laravel框架学习笔记之组件化开发实现方法
Feb 01 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
php读取excel文件示例分享(更新修改excel)
2014/02/27 PHP
php中base64_decode与base64_encode加密解密函数实例
2014/11/24 PHP
利用php输出不同的心形图案
2016/04/22 PHP
thinkphp配置文件路径的实现方法
2016/08/30 PHP
基于jquery的无限级联下拉框js插件
2011/10/29 Javascript
js实现省市联动效果的简单实例
2014/02/10 Javascript
jQuery插件开发详细教程
2014/06/06 Javascript
图解prototype、proto和constructor的三角关系
2016/07/31 Javascript
微信小程序之获取当前位置经纬度以及地图显示详解
2017/05/09 Javascript
JS简单实现数组去重的方法分析
2017/10/14 Javascript
ionic3实战教程之随机布局瀑布流的实现方法
2017/12/28 Javascript
微信小程序上线发布流程图文详解
2019/05/06 Javascript
解决layui 三级联动下拉框更新时回显的问题
2019/09/03 Javascript
vue之延时刷新实例
2019/11/14 Javascript
解决vue项目本地启动时无法携带cookie的问题
2021/02/06 Vue.js
python提示No module named images的解决方法
2014/09/29 Python
用TensorFlow实现戴明回归算法的示例
2018/05/02 Python
Python3实现获取图片文字里中文的方法分析
2018/12/13 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
Python编写一个验证码图片数据标注GUI程序附源码
2019/12/09 Python
Python操作Excel把数据分给sheet
2020/05/20 Python
美国休闲服装品牌:J.Crew Factory
2017/03/04 全球购物
世界上最大的曲棍球商店:Pro Hockey Life
2017/10/30 全球购物
印度首个本地在线平台:nearbuy
2019/03/28 全球购物
应届生服务员求职信
2013/10/31 职场文书
营销专业应届生求职信
2013/11/26 职场文书
高级编程求职信模板
2014/02/16 职场文书
公司年会抽奖活动主持词
2014/03/31 职场文书
英语专业自荐书
2014/06/13 职场文书
协会周年庆活动方案
2014/08/26 职场文书
2014年营业员工作总结
2014/11/18 职场文书
客房领班岗位职责
2015/02/11 职场文书
学校会议通知范文
2015/04/15 职场文书
Django项目如何正确配置日志(logging)
2021/04/29 Python
教你用python控制安卓手机
2021/05/13 Python