ThinkPHP权限认证Auth实例详解_PHP
本文以实例代码的形式深入剖析了ThinkPHP权限认证Auth的实现原理与方法,具体步骤如下:
mysql数据库部分sql代码:
-- ---------------------------- -- Table structure for think_auth_group -- ---------------------------- 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 AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户组表'; -- ---------------------------- -- Records of think_auth_group -- ---------------------------- INSERT INTO `think_auth_group` VALUES ('1', '管理组', '1', '1,2'); -- ---------------------------- -- Table structure for think_auth_group_access -- ---------------------------- DROP TABLE IF EXISTS `think_auth_group_access`; CREATE TABLE `think_auth_group_access` ( `uid` mediumint(8) unsigned NOT NULL COMMENT '用户id', `group_id` mediumint(8) unsigned NOT NULL COMMENT '用户组id', UNIQUE KEY `uid_group_id` (`uid`,`group_id`), KEY `uid` (`uid`), KEY `group_id` (`group_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户组明细表'; -- ---------------------------- -- Records of think_auth_group_access -- ---------------------------- INSERT INTO `think_auth_group_access` VALUES ('1', '1'); INSERT INTO `think_auth_group_access` VALUES ('1', '2'); -- ---------------------------- -- Table structure for think_auth_rule -- ---------------------------- 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 '' COMMENT '规则唯一标识', `title` char(20) NOT NULL DEFAULT '' COMMENT '规则中文名称', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:为1正常,为0禁用', `type` char(80) NOT NULL, `condition` char(100) NOT NULL DEFAULT '' COMMENT '规则表达式,为空表示存在就验证,不为空表示按照条件验证', PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='规则表'; -- ---------------------------- -- Records of think_auth_rule -- ---------------------------- INSERT INTO `think_auth_rule` VALUES ('1', 'Home/index', '列表', '1', 'Home', ''); INSERT INTO `think_auth_rule` VALUES ('2', 'Home/add', '添加', '1', 'Home', ''); INSERT INTO `think_auth_rule` VALUES ('3', 'Home/edit', '编辑', '1', 'Home', ''); INSERT INTO `think_auth_rule` VALUES ('4', 'Home/delete', '删除', '1', 'Home', ''); DROP TABLE IF EXISTS `think_user`; CREATE TABLE `think_user` ( `id` int(11) NOT NULL, `username` varchar(30) DEFAULT NULL, `password` varchar(32) DEFAULT NULL, `age` tinyint(2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of think_user -- ---------------------------- INSERT INTO `think_user` VALUES ('1', 'admin', '21232f297a57a5a743894a0e4a801fc3', '25');
配置文件Application\Common\Conf\config.php部分:
<?php return array( //'配置项'=>'配置值' 'DB_DSN' => '', // 数据库连接DSN 用于PDO方式 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => 'localhost', // 服务器地址 'DB_NAME' => 'thinkphp', // 数据库名 'DB_USER' => 'root', // 用户名 'DB_PWD' => 'root', // 密码 'DB_PORT' => 3306, // 端口 'DB_PREFIX' => 'think_', // 数据库表前缀 'AUTH_CONFIG' => array( 'AUTH_ON' => true, //认证开关 'AUTH_TYPE' => 1, // 认证方式,1为时时认证;2为登录认证。 'AUTH_GROUP' => 'think_auth_group', //用户组数据表名 'AUTH_GROUP_ACCESS' => 'think_auth_group_access', //用户组明细表 'AUTH_RULE' => 'think_auth_rule', //权限规则表 'AUTH_USER' => 'think_user'//用户信息表 ) );
项目Home控制器部分Application\Home\Controller\IndexController.class.php代码:
<?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { $Auth = new \Think\Auth(); //需要验证的规则列表,支持逗号分隔的权限规则或索引数组 $name = MODULE_NAME . '/' . ACTION_NAME; //当前用户id $uid = '1'; //分类 $type = MODULE_NAME; //执行check的模式 $mode = 'url'; //'or' 表示满足任一条规则即通过验证; //'and'则表示需满足所有规则才能通过验证 $relation = 'and'; if ($Auth->check($name, $uid, $type, $mode, $relation)) { die('认证:成功'); } else { die('认证:失败'); } } }
以上这些代码就是最基本的验证代码示例。
下面是源码阅读:
1、权限检验类初始化配置信息:
$Auth = new \Think\Auth();
创建一个对象时程序会合并配置信息
程序会合并Application\Common\Conf\config.php中的AUTH_CONFIG数组
public function __construct() { $prefix = C('DB_PREFIX'); $this->_config['AUTH_GROUP'] = $prefix . $this->_config['AUTH_GROUP']; $this->_config['AUTH_RULE'] = $prefix . $this->_config['AUTH_RULE']; $this->_config['AUTH_USER'] = $prefix . $this->_config['AUTH_USER']; $this->_config['AUTH_GROUP_ACCESS'] = $prefix . $this->_config['AUTH_GROUP_ACCESS']; if (C('AUTH_CONFIG')) { //可设置配置项 AUTH_CONFIG, 此配置项为数组。 $this->_config = array_merge($this->_config, C('AUTH_CONFIG')); } }
2、检查权限:
check($name, $uid, $type = 1, $mode = 'url', $relation = 'or')
大体分析一下这个方法
首先判断是否关闭权限校验 如果配置信息AUTH_ON=>false 则不会进行权限验证 否则继续验证权限
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 = array($name); } }
所以$name参数是不区分大小写的,最终都会转换成小写
开启url模式时全部转换为小写:
if ($mode == 'url') { $REQUEST = unserialize(strtolower(serialize($_REQUEST))); }
权限校验核心代码段之一,即循环所有该用户权限 判断 当前需要验证的权限 是否 在用户授权列表中:
foreach ($authList as $auth) { $query = preg_replace('/^.+\?/U', '', $auth);//获取url参数 if ($mode == 'url' && $query != $auth) { parse_str($query, $param); //获取数组形式url参数 $intersect = array_intersect_assoc($REQUEST, $param); $auth = preg_replace('/\?.*$/U', '', $auth);//获取访问的url文件 if (in_array($auth, $name) && $intersect == $param) { //如果节点相符且url参数满足 $list[] = $auth; } } else if (in_array($auth, $name)) { $list[] = $auth; } }
in_array($auth, $name) 如果 权限列表中 其中一条权限 等于 当前需要校验的权限 则加入到$list中
注:
$list = array(); //保存验证通过的规则名 if ($relation == 'or' and !empty($list)) { return true; } $diff = array_diff($name, $list); if ($relation == 'and' and empty($diff)) { return true; } $relation == 'or' and !empty($list); //当or时 只要有一条是通过的 则 权限为真 $relation == 'and' and empty($diff); //当and时 $name与$list完全相等时 权限为真
3、获取权限列表:
$authList = $this->getAuthList($uid, $type); //获取用户需要验证的所有有效规则列表
这个主要流程:
获取用户组
$groups = $this->getGroups($uid); //SELECT `rules` FROM think_auth_group_access a INNER JOIN think_auth_group g on a.group_id=g.id WHERE ( a.uid='1' and g.status='1' )
简化操作就是:
SELECT `rules` FROM think_auth_group WHERE STATUS = '1' AND id='1'//按正常流程 去think_auth_group_access表中内联有点多余....!
取得用户组rules规则字段 这个字段中保存的是think_auth_rule规则表的id用,分割
$ids就是$groups变量最终转换成的 id数组:
$map = array( 'id' => array('in', $ids), 'type' => $type, 'status' => 1, );
取得think_auth_rule表中的规则信息,之后循环:
foreach ($rules as $rule) { if (!empty($rule['condition'])) { //根据condition进行验证 $user = $this->getUserInfo($uid); //获取用户信息,一维数组 $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']); //dump($command);//debug @(eval('$condition=(' . $command . ');')); if ($condition) { $authList[] = strtolower($rule['name']); } } else { //只要存在就记录 $authList[] = strtolower($rule['name']); } } if (!empty($rule['condition'])) { //根据condition进行验证
这里就可以明白getUserInfo 会去获取配置文件AUTH_USER对应表名 去查找用户信息
重点是:
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']); @(eval('$condition=(' . $command . ');'));
'/\{(\w*?)\}/ 可以看成要匹配的文字为 {字符串} 那么 {字符串} 会替换成$user['字符串']
$command =$user['字符串']
如果
$rule['condition'] = '{age}'; $command =$user['age'] $rule['condition'] = '{age} > 5'; $command =$user['age'] > 10 @(eval('$condition=(' . $command . ');'));
即:
$condition=($user['age'] > 10);
这时再看下面代码 如果为真则加为授权列表
if ($condition) { $authList[] = strtolower($rule['name']); }

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds



Pour exécuter le projet ThinkPHP, vous devez : installer Composer ; utiliser Composer pour créer le projet ; entrer dans le répertoire du projet et exécuter php bin/console serve ; visiter http://localhost:8000 pour afficher la page d'accueil.

ThinkPHP dispose de plusieurs versions conçues pour différentes versions de PHP. Les versions majeures incluent 3.2, 5.0, 5.1 et 6.0, tandis que les versions mineures sont utilisées pour corriger les bogues et fournir de nouvelles fonctionnalités. La dernière version stable est ThinkPHP 6.0.16. Lorsque vous choisissez une version, tenez compte de la version PHP, des exigences en matière de fonctionnalités et du support de la communauté. Il est recommandé d'utiliser la dernière version stable pour de meilleures performances et une meilleure assistance.

Étapes pour exécuter ThinkPHP Framework localement : Téléchargez et décompressez ThinkPHP Framework dans un répertoire local. Créez un hôte virtuel (facultatif) pointant vers le répertoire racine ThinkPHP. Configurez les paramètres de connexion à la base de données. Démarrez le serveur Web. Initialisez l'application ThinkPHP. Accédez à l'URL de l'application ThinkPHP et exécutez-la.

Comparaison des performances des frameworks Laravel et ThinkPHP : ThinkPHP fonctionne généralement mieux que Laravel, en se concentrant sur l'optimisation et la mise en cache. Laravel fonctionne bien, mais pour les applications complexes, ThinkPHP peut être mieux adapté.

Étapes d'installation de ThinkPHP : Préparez les environnements PHP, Composer et MySQL. Créez des projets à l'aide de Composer. Installez le framework ThinkPHP et ses dépendances. Configurez la connexion à la base de données. Générez le code de l'application. Lancez l'application et visitez http://localhost:8000.

"Suggestions de développement : comment utiliser le framework ThinkPHP pour implémenter des tâches asynchrones" Avec le développement rapide de la technologie Internet, les applications Web ont des exigences de plus en plus élevées pour gérer un grand nombre de requêtes simultanées et une logique métier complexe. Afin d'améliorer les performances du système et l'expérience utilisateur, les développeurs envisagent souvent d'utiliser des tâches asynchrones pour effectuer certaines opérations chronophages, telles que l'envoi d'e-mails, le traitement des téléchargements de fichiers, la génération de rapports, etc. Dans le domaine de PHP, le framework ThinkPHP, en tant que framework de développement populaire, offre des moyens pratiques d'implémenter des tâches asynchrones.

ThinkPHP est un framework PHP hautes performances présentant des avantages tels que le mécanisme de mise en cache, l'optimisation du code, le traitement parallèle et l'optimisation des bases de données. Les tests de performances officiels montrent qu'il peut gérer plus de 10 000 requêtes par seconde et qu'il est largement utilisé dans les sites Web à grande échelle et les systèmes d'entreprise tels que JD.com et Ctrip dans les applications réelles.

Le service RPC basé sur ThinkPHP6 et Swoole implémente la fonction de transfert de fichiers Introduction : Avec le développement d'Internet, le transfert de fichiers est devenu de plus en plus important dans notre travail quotidien. Afin d'améliorer l'efficacité et la sécurité du transfert de fichiers, cet article présentera la méthode d'implémentation spécifique de la fonction de transfert de fichiers basée sur le service RPC basé sur ThinkPHP6 et Swoole. Nous utiliserons ThinkPHP6 comme framework Web et utiliserons la fonction RPC de Swoole pour réaliser le transfert de fichiers entre serveurs. 1. Norme environnementale
