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 相关文章推荐
我的论坛源代码(八)
Oct 09 PHP
PHP Global变量定义当前页面的全局变量实现探讨
Jun 05 PHP
体育彩票排列三组选三算法分享
Mar 07 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
Apr 10 PHP
php 购物车完整实现代码
Jun 05 PHP
CI框架在CLI下执行占用内存过大问题的解决方法
Jun 17 PHP
Cygwin中安装PHP方法步骤
Jul 04 PHP
PHP 接入微信扫码支付总结(总结篇)
Nov 03 PHP
Yii框架数据模型的验证规则rules()被执行的方法
Dec 02 PHP
php简单实现文件或图片强制下载的方法
Dec 06 PHP
PHP实现的微信APP支付功能示例【基于TP5框架】
Sep 16 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
May 14 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笔记之常用文件操作
2010/10/12 PHP
php 数组的一个悲剧?
2011/05/11 PHP
解析如何在PHP下载文件名中解决乱码的问题
2013/06/20 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
Yii框架连表查询操作示例
2019/09/06 PHP
JS的数组的扩展实例代码
2008/07/09 Javascript
javascript管中窥豹 形参与实参浅析
2011/12/17 Javascript
热点新闻滚动特效的js代码
2013/08/17 Javascript
js实现图片在未加载完成前显示加载中字样
2014/09/03 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
浅析BootStrap模态框的使用(经典)
2016/04/29 Javascript
【经验总结】编写JavaScript代码时应遵循的14条规律
2016/06/20 Javascript
详解nodejs中exports和module.exports的区别
2017/02/17 NodeJs
BootStrap表单验证 FormValidation 调整反馈图标位置的实例代码
2017/05/17 Javascript
使用DataTable插件实现异步加载数据
2017/11/19 Javascript
JavaScript的数据类型转换原则(干货)
2018/03/15 Javascript
JS如何实现手机端输入验证码效果
2020/05/13 Javascript
vue使用keep-alive实现组件切换时保存原组件数据方法
2020/10/30 Javascript
使用Python的Zato发送AMQP消息的教程
2015/04/16 Python
Python使用type关键字创建类步骤详解
2019/07/23 Python
Python3爬虫关于识别点触点选验证码的实例讲解
2020/07/30 Python
python装饰器三种装饰模式的简单分析
2020/09/04 Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
2020/09/29 Python
低碳环保口号
2014/06/12 职场文书
关于环保的标语
2014/06/13 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
2014年个人售房协议书
2014/10/30 职场文书
2015年财务经理工作总结
2015/05/13 职场文书
亮剑观后感
2015/06/05 职场文书
使用pandas或numpy处理数据中的空值(np.isnan()/pd.isnull())
2021/05/14 Python
JS如何实现基于websocket的多端桥接平台
2021/05/14 Javascript
安装pytorch时报sslerror错误的解决方案
2021/05/17 Python
浅谈Redis的keys命令到底有多慢
2021/10/05 Redis
高并发下Redis如何保持数据一致性(避免读后写)
2022/03/18 Redis
python数字图像处理:图像简单滤波
2022/06/28 Python