搜索
首页后端开发php教程TP5之Auth权限管理实例

TP5之Auth权限管理实例

Dec 27, 2017 pm 06:04 PM
auth实例权限

权限管理是一个项目中必不可少的模块之一,常用的有RBAC、Auth等。本文就分享在TP5中通过Auth验证权限的实例,希望对大家有所帮助。

<?php
namespace think;
use think\Config;
use think\Session;
use think\Db;
/**
 * 权限认证类
 */
//数据库
/*
  -- ----------------------------
  -- mt4_auth_rule,规则表,
  -- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
  -- ----------------------------
  DROP TABLE IF EXISTS `mt4_auth_rule`;
  CREATE TABLE `mt4_auth_rule` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `name` char(80) NOT NULL DEFAULT &#39;&#39;,
  `title` char(20) NOT NULL DEFAULT &#39;&#39;,
  `type` tinyint(1) NOT NULL DEFAULT &#39;1&#39;,
  `status` tinyint(1) NOT NULL DEFAULT &#39;1&#39;,
  `condition` char(100) NOT NULL DEFAULT &#39;&#39;,  # 规则附件条件,满足附加条件的规则,才认为是有效的规则
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
  ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  -- ----------------------------
  -- mt4_auth_group 用户组表,
  -- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
  -- ----------------------------
  DROP TABLE IF EXISTS `mt4_auth_group`;
  CREATE TABLE `mt4_auth_group` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `title` char(100) NOT NULL DEFAULT &#39;&#39;,
  `status` tinyint(1) NOT NULL DEFAULT &#39;1&#39;,
  `rules` char(80) NOT NULL DEFAULT &#39;&#39;,
  PRIMARY KEY (`id`)
  ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  -- ----------------------------
  -- mt4_auth_group_access 用户组明细表
  -- uid:用户id,group_id:用户组id
  -- ----------------------------
  DROP TABLE IF EXISTS `mt4_auth_group_access`;
  CREATE TABLE `mt4_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 {
    //默认配置
    protected $config = array(
        &#39;auth_on&#39;           => true,                      // 认证开关
        &#39;auth_type&#39;         => 2,                         // 认证方式,1为实时认证;2为登录认证。
        &#39;auth_group&#39;        => &#39;auth_group&#39;,        // 用户组数据表名
        &#39;auth_group_access&#39; => &#39;auth_group_access&#39;, // 用户-用户组关系表
        &#39;auth_rule&#39;         => &#39;auth_rule&#39;,         // 权限规则表
        &#39;auth_user&#39;         => &#39;auth_admin&#39;             // 用户信息表
    );
    
    public function __construct() {
        if (Config::get(&#39;auth_config&#39;)) {
            $this->config = array_merge($this->config, Config::get(&#39;auth_config&#39;)); //可设置配置项 auth_config, 此配置项为数组。
        }
    }
    /**
     * 检查权限
     * @param name string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组
     * @param uid  int           认证用户的id
     * @param string mode        执行check的模式
     * @param relation string    如果为 &#39;or&#39; 表示满足任一条规则即通过验证;如果为 &#39;and&#39;则表示需满足所有规则才能通过验证
     * return boolean           通过验证返回true;失败返回false
     */
    public function check($name, $uid, $type = 1, $mode = &#39;url&#39;, $relation = &#39;or&#39;) {
        if (!$this->config[&#39;auth_on&#39;]) {
            return true;
        }
        $authList = $this->getAuthList($uid, $type); //获取用户需要验证的所有有效规则列表
        if (is_string($name)) {
            $name = strtolower($name);
//            if (strpos($name, &#39;,&#39;) !== false) {
//                $name = explode(&#39;,&#39;, $name);
//            } else {
//                $name = [$name];
//            }
            $name = strpos($name, &#39;,&#39;) !== false ? explode(&#39;,&#39;, $name) : [$name];
        }
        $list = []; //保存验证通过的规则名
        if ($mode == &#39;url&#39;) {
            $REQUEST = unserialize(strtolower(serialize($_REQUEST)));
        }
        foreach ($authList as $auth) {
            $query = preg_replace(&#39;/^.+\?/U&#39;, &#39;&#39;, $auth);
            if ($mode == &#39;url&#39; && $query != $auth) {
                parse_str($query, $param); //解析规则中的param
                $intersect = array_intersect_assoc($REQUEST, $param);
                $auth = preg_replace(&#39;/\?.*$/U&#39;, &#39;&#39;, $auth);
                if (in_array($auth, $name) && $intersect == $param) {  //如果节点相符且url参数满足
                    $list[] = $auth;
                }
            } else if (in_array($auth, $name)) {
                $list[] = $auth;
            }
        }
        if ($relation == &#39;or&#39; and ! empty($list)) {
            return false;
        }
        $diff = array_diff($name, $list);
        if ($relation == &#39;and&#39; and empty($diff)) {
            return false;
        }
        return true;
    }
    /**
     * 根据用户id获取用户组,返回值为数组
     * @param  uid int     用户id
     * return array       用户所属的用户组 [
     *     [&#39;uid&#39;=>&#39;用户id&#39;,&#39;group_id&#39;=>&#39;用户组id&#39;,&#39;title&#39;=>&#39;用户组名称&#39;,&#39;rules&#39;=>&#39;用户组拥有的规则id,多个,号隔开&#39;),
     *     ...)   
     */
    public function getGroups($uid) {
        static $groups = [];
        if (isset($groups[$uid])) {
            return $groups[$uid];
        }
        $user_groups = Db::view($this->config[&#39;auth_group_access&#39;], &#39;uid,group_id&#39;)->view($this->config[&#39;auth_group&#39;], &#39;title,rules&#39;, "{$this->config[&#39;auth_group_access&#39;]}.group_id={$this->config[&#39;auth_group&#39;]}.id")
                        ->where([&#39;uid&#39; => $uid, &#39;status&#39; => 1])->select();
        $groups[$uid] = $user_groups ? $user_groups : [];
        return $groups[$uid];
    }
    /**
     * 获得权限列表
     * @param integer $uid  用户id
     * @param integer $type 
     */
    protected function getAuthList($uid, $type) {
        static $_authList = []; //保存用户验证通过的权限列表
        $t = implode(&#39;,&#39;, (array) $type);
        if (isset($_authList[$uid . $t])) {
            return $_authList[$uid . $t];
        }
        if ($this->config[&#39;auth_type&#39;] == 2 && Session::has(&#39;_auth_list_&#39; . $uid . $t)) {
            return Session::get(&#39;_auth_list_&#39; . $uid . $t);
        }
        //读取用户所属用户组
        $groups = $this->getGroups($uid);
        $ids = []; //保存用户所属用户组设置的所有权限规则id
        foreach ($groups as $g) {
            $ids = array_merge($ids, explode(&#39;,&#39;, trim($g[&#39;rules&#39;], &#39;,&#39;)));
        }
        $ids = array_unique($ids);
        if (empty($ids)) {
            $_authList[$uid . $t] = [];
            return [];
        }
        $map = [
            &#39;id&#39; => [&#39;notin&#39;, $ids],
            &#39;type&#39; => $type,
            &#39;status&#39; => 1,
        ];
        //读取用户组所有权限规则
        $rules = Db::name($this->config[&#39;auth_rule&#39;])->where($map)->field(&#39;condition,name&#39;)->select();
        //循环规则,判断结果。
        $authList = [];   //
        foreach ($rules as $rule) {
            if (!empty($rule[&#39;condition&#39;])) { //根据condition进行验证
                $this->getUserInfo($uid); //获取用户信息,一维数组
                $command = preg_replace(&#39;/\{(\w*?)\}/&#39;, &#39;$user[\&#39;\\1\&#39;]&#39;, $rule[&#39;condition&#39;]);
                @(eval(&#39;$condition=(&#39; . $command . &#39;);&#39;));
                $condition && $authList[] = strtolower($rule[&#39;name&#39;]);
            } else {
                $authList[] = strtolower($rule[&#39;name&#39;]); //只要存在就记录
            }
        }
        $_authList[$uid . $t] = $authList;
        if ($this->config[&#39;auth_type&#39;] == 2) {
            $_SESSION[&#39;_auth_list_&#39; . $uid . $t] = $authList; //规则列表结果保存到session
        }
        return array_unique($authList);
    }
    /**
     * 获得用户资料,根据自己的情况读取数据库
     */
    protected function getUserInfo($uid) {
        static $userinfo = [];
        if (!isset($userinfo[$uid])) {
            $userinfo[$uid] = Db::name($this->config[&#39;auth_user&#39;])->where([&#39;uid&#39; => $uid])->find();
        }
        return $userinfo[$uid];
    }
}

相关推荐:

PHP实现权限管理功能的方法

ThinkPHP(RBAC)权限管理视频以及资料(源码、课件)分享

php实例-php 人员权限管理(RBAC)实例(推荐)

以上是TP5之Auth权限管理实例的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP如何识别用户的会话?PHP如何识别用户的会话?May 01, 2025 am 12:23 AM

phpientifiesauser'ssessionusessessionSessionCookiesAndSessionIds.1)whiwSession_start()被称为,phpgeneratesainiquesesesessionIdStoredInacookInAcookInamedInAcienamedphpsessidontheuser'sbrowser'sbrowser.2)thisIdAllowSphptptpptpptpptpptortoreTessessionDataAfromtheserverMtheserver。

确保PHP会议的一些最佳实践是什么?确保PHP会议的一些最佳实践是什么?May 01, 2025 am 12:22 AM

PHP会话的安全可以通过以下措施实现:1.使用session_regenerate_id()在用户登录或重要操作时重新生成会话ID。2.通过HTTPS协议加密传输会话ID。3.使用session_save_path()指定安全目录存储会话数据,并正确设置权限。

PHP会话文件默认存储在哪里?PHP会话文件默认存储在哪里?May 01, 2025 am 12:15 AM

phpsessionFilesArestoredIntheDirectorySpecifiedBysession.save_path,通常是/tmponunix-likesystemsorc:\ windows \ windows \ temponwindows.tocustomizethis:tocustomizEthis:1)useession_save_save_save_path_path()

您如何从PHP会话中检索数据?您如何从PHP会话中检索数据?May 01, 2025 am 12:11 AM

ToretrievedatafromaPHPsession,startthesessionwithsession_start()andaccessvariablesinthe$_SESSIONarray.Forexample:1)Startthesession:session_start().2)Retrievedata:$username=$_SESSION['username'];echo"Welcome,".$username;.Sessionsareserver-si

您如何使用会议来实施购物车?您如何使用会议来实施购物车?May 01, 2025 am 12:10 AM

利用会话构建高效购物车系统的步骤包括:1)理解会话的定义与作用,会话是服务器端的存储机制,用于跨请求维护用户状态;2)实现基本的会话管理,如添加商品到购物车;3)扩展到高级用法,支持商品数量管理和删除;4)优化性能和安全性,通过持久化会话数据和使用安全的会话标识符。

您如何在PHP中创建和使用接口?您如何在PHP中创建和使用接口?Apr 30, 2025 pm 03:40 PM

本文解释了如何创建,实施和使用PHP中的接口,重点关注其对代码组织和可维护性的好处。

crypt()和password_hash()有什么区别?crypt()和password_hash()有什么区别?Apr 30, 2025 pm 03:39 PM

本文讨论了PHP中的crypt()和password_hash()之间的差异,以进行密码哈希,重点介绍其实施,安全性和对现代Web应用程序的适用性。

如何防止PHP中的跨站点脚本(XSS)?如何防止PHP中的跨站点脚本(XSS)?Apr 30, 2025 pm 03:38 PM

文章讨论了通过输入验证,输出编码以及使用OWASP ESAPI和HTML净化器之类的工具来防止PHP中的跨站点脚本(XSS)。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。