thinkPHP5 ACL用户权限模块用法详解


Posted in PHP onMay 10, 2017

本文实例讲述了thinkPHP5 ACL用户权限模块用法。分享给大家供大家参考,具体如下:

最近学习thinkphp5,和以前3.X版本是完全不是一个概念。学习thinkphp5的朋友要注意命名空间思想。

最近做的一个项目,一个检测管理系统,由于为了以后做APP需要,才切换到thinkphp5作为以后的扩展API用的。今天完成的是用户权限控制模块。我把这个mark下来

数据库:

role数据库表:

`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL COMMENT '角色名称',
`pid` smallint(6) DEFAULT NULL COMMENT '父角色ID',
`rule_name` text COMMENT '规则唯一英文标识,全小写',
`type` varchar(50) DEFAULT '' COMMENT '权限规则分类,请加应用前缀,如admin_',
`status` tinyint(1) unsigned DEFAULT NULL COMMENT '状态',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`listorder` int(3) NOT NULL DEFAULT '0' COMMENT '排序字段',

auth_rule数据库表:

`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '规则id,自增主键',
`module` varchar(20) NOT NULL COMMENT '规则所属module',
`type` varchar(30) NOT NULL DEFAULT '1' COMMENT '权限规则分类,请加应用前缀,如admin_',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '规则唯一英文标识,全小写',
`param` varchar(255) DEFAULT NULL COMMENT '额外url参数',
`title` varchar(20) NOT NULL DEFAULT '' COMMENT '规则中文描述',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效(0:无效,1:有效)',
`condition` varchar(300) NOT NULL DEFAULT '' COMMENT '规则附加条件',

用户表里面增加:

`pools` varchar(20) DEFAULT '' COMMENT '权限池',
`roleId` smallint(5) NOT NULL DEFAULT '0' COMMENT '权限id',

代码如下:

iAuth.php 权限认证的公共库文件

class iAuth{
  public $user = null;
  //默认配置
  protected $_config = array(
  );
  public function __construct() {
  }
  /**
   * 检查权限
   * @param name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
   * @param uid int      认证用户的id
   * @param relation string  如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
   * @return boolean      通过验证返回true;失败返回false
   */
  public function check($uid,$name,$relation='or') {
    if(empty($uid)){
      return false;
    }
    if($uid==1){
      return true;
    }
    if (is_string($name)) {
      $name = strtolower($name);
      if (strpos($name, ',') !== false) {
        $name = explode(',', $name);
      } else {
        $name = array($name);
      }
    }
    $list = array(); //保存验证通过的规则名
    //获取用户信息
    $this->getUserInfo($uid);//获取用户信息,一维数组
    $groups= $this->user['roleId'];
    if(in_array(1, $groups)){
      return true;
    }
    if(empty($groups)){
      return false;
    }
    $rules = self::get_rules($this->user['roleId']);
    if(in_array($name,$rules))
    {
      return true;
    }
    return false;
  }
  /**
   * 获得用户资料
   */
  private function getUserInfo(&$uid) {
    if(!isset($this->user)){
      $user = new Users($uid);
      $this->user = $user->fields;
    }
    return $this->user;
  }
  /**
   * 获取验证规则
   * @param int $id
   */
  public static function get_rules($id)
  {
    if(empty($id)) return false;
    $rules = Cache::get(self::$cache_prefix . $id);
    if(empty($rules))
    {
      $model = Db::name('role');
      $model->where('id',$id);
      $rules = $model->find();
      $rules['rule_name'] = explode(',',strtolower($rules['rule_name']));
      //设置缓存
      Cache::set(self::$cache_prefix,$rules);
    }
    return $rules;
  }
}

Common.php 通用函数类库

/**
 * 检测用户id
 * @param name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
 * @param uid int      认证用户的id
 */
function sp_auth_check($uid, $name=null)
{
  if(empty($uid)) return false;
  if(empty($name)){
    $name=strtolower(MODULE_NAME."/".CONTROLLER_NAME."/".ACTION_NAME);
  }
  $iAuth_obj = new \app\Common\Lib\iAuth();
  return $iAuth_obj->check($uid);
}

AdminbaseController.php 后台管理的父控制器类

class AdminbaseController extends Controller
{
  public $uid = 0;
  //用户实例
  public $userObj = null;
  /**
   * 构造函数
   * Adminbase constructor.
   */
  public function __construct()
  {
    parent::__construct();
  }
  public function _initialize()
  {
    $this->uid = Session::read('AdminId');
    if(!empty($this->uid ))
    {
      //检测过已经登录了
      $this->userObj = Db::name('users')->where('uid',$this->uid)->find();
      if(!$this->check_access($this->uid))
      {
        $this->error("您没有访问权限!",Url::build('admin/index/login'));
        exit();
      }
      $this->assign('admin',$this->userObj);
    }
    else
    {
      //没有登录的
      $this->error("您还没有登录!",Url::build('admin/index/login'));
      exit();
    }
  }
  /**
   * 检测权限
   * @param $uid
   */
  private function check_access(&$uid)
  {
    if($uid == 1)
    {
      //超级管理员
      return true;
    }
    $request = Request::instance();
    //如果不是这个应用池的账户也不通过
    $pools = explode(',',$this->userObj['pools']);
    if(!in_array(strtolower($request->module()), $pools))  return false;
    $rule = $request->module() . '_' . $request->controller() . '_' . $request->action() ;
    $no_need_check_rules = Config::get('inc_auth.no_need_check_rules');
    if(!in_array(strtolower($rule),$no_need_check_rules))
    {
      //验证权限
      return sp_auth_check($uid);
    }
    else
    {
      return true;
    }
  }
}

inc_auth.php 认证配置文件

$config['no_need_check_rules'] = array('admin_index_index','admin_index_login');

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

PHP 相关文章推荐
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
Jun 11 PHP
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
Jun 09 PHP
php中通过正则表达式下载内容中的远程图片的函数代码
Jan 10 PHP
测试PHP连接MYSQL成功与否的代码
Aug 16 PHP
php数据类型判断函数有哪些
Sep 23 PHP
php 购物车完整实现代码
Jun 05 PHP
PHP图片自动裁切应付不同尺寸的显示
Oct 16 PHP
PHP缓存集成库phpFastCache用法
Dec 15 PHP
PHP的pcntl多进程用法实例
Mar 19 PHP
php查询whois信息的方法
Jun 08 PHP
标准版Eclipse搭建PHP环境的详细步骤
Nov 18 PHP
解决在Laravel 中处理OPTIONS请求的问题
Oct 11 PHP
使用WAMP搭建PHP本地开发环境
May 10 #PHP
thinkPHP5 tablib标签库自定义方法详解
May 10 #PHP
PHP实现获取第一个中文首字母并进行排序的方法
May 09 #PHP
php7 安装yar 生成docker镜像
May 09 #PHP
php简单生成一组与多组随机字符串的方法
May 09 #PHP
PHP实现上传多图即时显示与即时删除的方法
May 09 #PHP
Laravel中如何增加自定义全局函数详解
May 09 #PHP
You might like
PHP 的几个配置文件函数
2006/12/21 PHP
PHP跳转页面的几种实现方法详解
2013/06/08 PHP
Session服务器配置指南与使用经验的深入解析
2013/06/17 PHP
利用CSS、JavaScript及Ajax实现高效的图片预加载
2013/10/16 Javascript
比较新旧两个数组值得增加和删除的JS代码
2013/10/30 Javascript
js弹出确认是否删除对话框
2014/03/27 Javascript
jquery实现点击文字可编辑并修改保存至数据库
2014/04/15 Javascript
使用jQuery中的when实现多个AJAX请求对应单个回调的例子分享
2014/04/23 Javascript
跟我学Node.js(四)---Node.js的模块载入方式与机制
2014/06/04 Javascript
一行命令搞定node.js 版本升级
2014/07/20 Javascript
canvas绘制一个常用的emoji表情
2017/03/30 Javascript
基于对象合并功能的实现示例
2017/10/10 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
2018/02/09 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
viewer.js实现图片预览功能
2020/06/24 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
2020/07/19 Javascript
python益智游戏计算汉诺塔问题示例
2014/03/05 Python
python利用OpenCV2实现人脸检测
2020/04/16 Python
机器学习经典算法-logistic回归代码详解
2017/12/22 Python
python用户评论标签匹配的解决方法
2018/05/31 Python
python实现按长宽比缩放图片
2018/06/07 Python
用python生成1000个txt文件的方法
2018/10/25 Python
Python os.access()用法实例
2019/02/18 Python
python制作简单五子棋游戏
2019/06/18 Python
django fernet fields字段加密实践详解
2019/08/12 Python
基于pytorch的保存和加载模型参数的方法
2019/08/17 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
Java的类可以定义为Protected或者Private得吗
2015/09/25 面试题
电大毕业生自我鉴定
2013/11/10 职场文书
我爱我家教学反思
2014/05/01 职场文书
环保宣传标语
2014/06/12 职场文书
2014年计划生育工作总结
2014/11/14 职场文书
2016秋季运动会开幕词
2016/03/04 职场文书
Java 获取Word中所有的插入和删除修订的方法
2022/04/06 Java/Android