原文地址:https://blog.csdn.net/qq_33257081/article/details/79137190

下面本人为大家讲解一下如何实现auth权限,
第一步,新建Auth.php,复制下面的代码,把注释中的表都创建一下。把文件放到extend新建文件夹org放进去即可,
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: luofei614 <weibo.com/luofei614>
// +----------------------------------------------------------------------
// | 修改者: anuo (本权限类在原3.2.3的基础上修改过来的)
// +----------------------------------------------------------------------
use think\Db;
use think\Config;
use think\Session;
use think\Request;
use think\Loader; /**
* 权限认证类
* 功能特性:
* 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
* $auth=new Auth(); $auth->check('规则名称','用户id')
* 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
* $auth=new Auth(); $auth->check('规则1,规则2','用户id','and')
* 第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。 当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or
* 3,一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限)
* 4,支持规则表达式。
* 在think_auth_rule 表中定义一条规则时,如果type为1, condition字段就可以定义规则表达式。 如定义{score}>5 and {score}<100
* 表示用户的分数在5-100之间时这条规则才会通过。
*/
//数据库
/*
-- ----------------------------
-- think_auth_rule,规则表,
-- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_rule`;
CREATE TABLE `think_auth_rule` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` char(80) NOT NULL DEFAULT '',
`title` char(20) NOT NULL DEFAULT '',
`type` tinyint(1) NOT NULL DEFAULT '1',
`status` tinyint(1) NOT NULL DEFAULT '1',
`condition` char(100) NOT NULL DEFAULT '', # 规则附件条件,满足附加条件的规则,才认为是有效的规则
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- think_auth_group 用户组表,
-- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_group`;
CREATE TABLE `think_auth_group` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`title` char(100) NOT NULL DEFAULT '',
`status` tinyint(1) NOT NULL DEFAULT '1',
`rules` char(80) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- think_auth_group_access 用户组明细表
-- uid:用户id,group_id:用户组id
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_group_access`;
CREATE TABLE `think_auth_group_access` (
`uid` mediumint(8) unsigned NOT NULL,
`group_id` mediumint(8) unsigned NOT NULL,
UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
KEY `uid` (`uid`),
KEY `group_id` (`group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
*/ class Auth
{
/**
* @var object 对象实例
*/
protected static $instance;
/**
* 当前请求实例
* @var Request
*/
protected $request; //默认配置
protected $config = [
'auth_on' => 1, // 权限开关
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
'auth_group' => 'auth_group', // 用户组数据表名
'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
'auth_rule' => 'auth_rule', // 权限规则表
'auth_user' => 'member', // 用户信息表
]; /**
* 类架构函数
* Auth constructor.
*/
public function __construct()
{
//可设置配置项 auth, 此配置项为数组。
if ($auth = Config::get('auth')) {
$this->config = array_merge($this->config, $auth);
}
// 初始化request
$this->request = Request::instance();
} /**
* 初始化
* @access public
* @param array $options 参数
* @return \think\Request
*/
public static function instance($options = [])
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
} return self::$instance;
} /**
* 检查权限
* @param $name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
* @param $uid int 认证用户的id
* @param int $type 认证类型
* @param string $mode 执行check的模式
* @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
* @return bool 通过验证返回true;失败返回false
*/
public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or')
{
if (!$this->config['auth_on']) {
return true;
}
// 获取用户需要验证的所有有效规则列表
$authList = $this->getAuthList($uid, $type);
if (is_string($name)) {
$name = strtolower($name);
if (strpos($name, ',') !== false) {
$name = explode(',', $name);
} else {
$name = [$name];
}
}
$list = []; //保存验证通过的规则名
if ('url' == $mode) {
$REQUEST = unserialize(strtolower(serialize($this->request->param())));
}
foreach ($authList as $auth) {
$query = preg_replace('/^.+\?/U', '', $auth);
if ('url' == $mode && $query != $auth) {
parse_str($query, $param); //解析规则中的param
$intersect = array_intersect_assoc($REQUEST, $param);
$auth = preg_replace('/\?.*$/U', '', $auth);
if (in_array($auth, $name) && $intersect == $param) {
//如果节点相符且url参数满足
$list[] = $auth;
}
} else {
if (in_array($auth, $name)) {
$list[] = $auth;
}
}
}
if ('or' == $relation && !empty($list)) {
return true;
}
$diff = array_diff($name, $list);
if ('and' == $relation && empty($diff)) {
return true;
} return false;
} /**
* 根据用户id获取用户组,返回值为数组
* @param $uid int 用户id
* @return array 用户所属的用户组 array(
* array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
* ...)
*/
public function getGroups($uid)
{
static $groups = [];
if (isset($groups[$uid])) {
return $groups[$uid];
}
// 转换表名
$auth_group_access = Loader::parseName($this->config['auth_group_access'], 1);
$auth_group = Loader::parseName($this->config['auth_group'], 1);
// 执行查询
$user_groups = Db::view($auth_group_access, 'uid,group_id')
->view($auth_group, 'title,rules', "{$auth_group_access}.group_id={$auth_group}.id", 'LEFT')
->where("{$auth_group_access}.uid='{$uid}' and {$auth_group}.status='1'")
->select();
$groups[$uid] = $user_groups ?: []; return $groups[$uid];
} /**
* 获得权限列表
* @param integer $uid 用户id
* @param integer $type
* @return array
*/
protected function getAuthList($uid, $type)
{
static $_authList = []; //保存用户验证通过的权限列表
$t = implode(',', (array)$type);
if (isset($_authList[$uid . $t])) {
return $_authList[$uid . $t];
}
if (2 == $this->config['auth_type'] && Session::has('_auth_list_' . $uid . $t)) {
return Session::get('_auth_list_' . $uid . $t);
}
//读取用户所属用户组
$groups = $this->getGroups($uid);
$ids = []; //保存用户所属用户组设置的所有权限规则id
foreach ($groups as $g) {
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
}
$ids = array_unique($ids);
if (empty($ids)) {
$_authList[$uid . $t] = []; return [];
}
$map = [
'id' => ['in', $ids],
'type' => $type
];
//读取用户组所有权限规则
$rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,name')->select();
//循环规则,判断结果。
$authList = []; //
foreach ($rules as $rule) {
if (!empty($rule['condition'])) {
//根据condition进行验证
$user = $this->getUserInfo($uid); //获取用户信息,一维数组
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
@(eval('$condition=(' . $command . ');'));
if ($condition) {
$authList[] = strtolower($rule['name']);
}
} else {
//只要存在就记录
$authList[] = strtolower($rule['name']);
}
}
$_authList[$uid . $t] = $authList;
if (2 == $this->config['auth_type']) {
//规则列表结果保存到session
Session::set('_auth_list_' . $uid . $t, $authList);
} return array_unique($authList);
} /**
* 获得用户资料
* @param $uid
* @return mixed
*/
protected function getUserInfo($uid)
{
static $user_info = []; $user = Db::name($this->config['auth_user']);
// 获取用户表主键
$_pk = is_string($user->getPk()) ? $user->getPk() : 'uid';
if (!isset($user_info[$uid])) {
$user_info[$uid] = $user->where($_pk, $uid)->find();
} return $user_info[$uid];
}
}

第二步 新建控制器,其它的权限添加就不多说了,下面是验证最终结果

<?php
namespace app\admin\controller;
use \think\Controller;
use think\Loader;
class Base extends Controller
{
    protected $current_action;
    public function _initialize()
    {
        Loader::import("org/Auth", EXTEND_PATH);
        $auth=new \Auth();
        $this->current_action = request()->module().'/'.request()->controller().'/'.lcfirst(request()->action());
        $result = $auth->check($this->current_action,session('user_id'));
        if($result){
            echo "权限验证成功";
        }
    }
}

tp5Auth权限实现的更多相关文章

  1. tp5---auth权限搭建2

    1.auth权限 composer auth库 下载完成之后 根据auth.php中所提及怎样创建表,就怎样建表 2.安利一个简单的建表操作 根据composer下载里的文件注释的代码,将其直接放到s ...

  2. 隐私泄露杀手锏 —— Flash 权限反射

    [简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...

  3. 【.net 深呼吸】限制执行代码的权限

    前面好几篇文章,老周都跟大伙伴们聊了跟应用程序域有关的话题,干脆咱们一聊到底吧,做学问就应该这样,有恒心. App Domain的创建新应用程序域的方法中,有一个特殊的重载: public stati ...

  4. Android 6.0 权限知识学习笔记

    最近在项目上因为6.0运行时权限吃了亏,发现之前对运行时权限的理解不足,决定回炉重造,重新学习一下Android Permission. 进入正题: Android权限 在Android系统中,权限分 ...

  5. Android数据存储之Android 6.0运行时权限下文件存储的思考

    前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以 ...

  6. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

  7. Android权限管理之Android 6.0运行时权限及解决办法

    前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...

  8. Android权限管理之Permission权限机制及使用

    前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...

  9. shiro权限管理框架与springmvc整合

    shiro是apache下的一个项目,和spring security类似,用于用户权限的管理‘ 但从易用性和学习成本上考虑,shiro更具优势,同时shiro支持和很多接口集成 用户及权限管理是众多 ...

随机推荐

  1. Unity3D Shader 内置函数

    Intrinsic Functions (DirectX HLSL) The following table lists the intrinsic functions available in HL ...

  2. python 中面向对象的概念

    原文 域和作用空间 本地域,函数域(nonlocal)和 全局域(global) def scope_test(): def do_local(): spam = "local spam&q ...

  3. 夺冠概率|2012年蓝桥杯B组题解析第九题-fishers

    (17')夺冠概率 足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能. 假设有甲.乙.丙.丁四个球队.根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表: 甲 乙 丙 丁 甲 - 0. ...

  4. Flask web开发之路六

    紧接着上篇文档,写模板继承和block,URL链接和加载静态文件 模板继承和block 项目结构 主app文件代码: from flask import Flask,render_template a ...

  5. Red Hat6设置使用CentOS的yum源

    环境查看 red hat系统使用自己默认的yum源未注册在使用yum安装软件的时候会出现以下错误提示 可以修改成centos的yum源 卸载yum软件 rpm -qa|grep yum|xargs r ...

  6. 大疆OSMO口袋云台相机惊艳上市!友商该如何是好。。。

    2018.11.29 晚上更新: 下午看了大疆新出的口袋云台摄像机,感觉棒极了,于是我立刻去了京东下单预订了.目前是可以免息分期6个月就可以搞定了.‘ 大家敬请期待我的评测视频吧. ======== ...

  7. .NET Core开发日志——Global Tools

    .NET Core 2.1引入了一个新的功能,Global Tools,其本质是包含控制台应用程序的nuget包,目前而言,还没有特别有用的工具,不过相信随着时间的推移,各种有创意或者实用性强的Glo ...

  8. POJ 1451 - T9 - [字典树]

    题目链接:http://bailian.openjudge.cn/practice/1451/ 总时间限制: 1000ms 内存限制: 65536kB 描述 Background A while ag ...

  9. rabbitmq简单实例

    JMS组件:activemq(慢)AMQP组件(advance message queue protocol):rabbitmq和kafka 一..消息队列解决了什么问题?异步处理应用解耦流量削锋日志 ...

  10. Django:模板template(一)

    把模板的过程.语法.标签.反向地址解析.过滤器.模板继承与HTML转义记下笔记 1.概述及demo 动态生成HTML 模板的设计实现业务逻辑(View)和显示内容(template)的分离 一个模板可 ...