当前位置:Gxlcms > PHP教程 > TP5之Auth权限管理实例

TP5之Auth权限管理实例

时间:2021-07-01 10:21:17 帮助过:8人阅读

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

  1. <?php
  2. namespace think;
  3. use think\Config;
  4. use think\Session;
  5. use think\Db;
  6. /**
  7. * 权限认证类
  8. */
  9. //数据库
  10. /*
  11. -- ----------------------------
  12. -- mt4_auth_rule,规则表,
  13. -- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
  14. -- ----------------------------
  15. DROP TABLE IF EXISTS `mt4_auth_rule`;
  16. CREATE TABLE `mt4_auth_rule` (
  17. `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  18. `name` char(80) NOT NULL DEFAULT '',
  19. `title` char(20) NOT NULL DEFAULT '',
  20. `type` tinyint(1) NOT NULL DEFAULT '1',
  21. `status` tinyint(1) NOT NULL DEFAULT '1',
  22. `condition` char(100) NOT NULL DEFAULT '', # 规则附件条件,满足附加条件的规则,才认为是有效的规则
  23. PRIMARY KEY (`id`),
  24. UNIQUE KEY `name` (`name`)
  25. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  26. -- ----------------------------
  27. -- mt4_auth_group 用户组表,
  28. -- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
  29. -- ----------------------------
  30. DROP TABLE IF EXISTS `mt4_auth_group`;
  31. CREATE TABLE `mt4_auth_group` (
  32. `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  33. `title` char(100) NOT NULL DEFAULT '',
  34. `status` tinyint(1) NOT NULL DEFAULT '1',
  35. `rules` char(80) NOT NULL DEFAULT '',
  36. PRIMARY KEY (`id`)
  37. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  38. -- ----------------------------
  39. -- mt4_auth_group_access 用户组明细表
  40. -- uid:用户id,group_id:用户组id
  41. -- ----------------------------
  42. DROP TABLE IF EXISTS `mt4_auth_group_access`;
  43. CREATE TABLE `mt4_auth_group_access` (
  44. `uid` mediumint(8) unsigned NOT NULL,
  45. `group_id` mediumint(8) unsigned NOT NULL,
  46. UNIQUE KEY `uid_group_id` (`uid`,`group_id`),
  47. KEY `uid` (`uid`),
  48. KEY `group_id` (`group_id`)
  49. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  50. */
  51. class Auth {
  52. //默认配置
  53. protected $config = array(
  54. 'auth_on' => true, // 认证开关
  55. 'auth_type' => 2, // 认证方式,1为实时认证;2为登录认证。
  56. 'auth_group' => 'auth_group', // 用户组数据表名
  57. 'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
  58. 'auth_rule' => 'auth_rule', // 权限规则表
  59. 'auth_user' => 'auth_admin' // 用户信息表
  60. );
  61. public function __construct() {
  62. if (Config::get('auth_config')) {
  63. $this->config = array_merge($this->config, Config::get('auth_config')); //可设置配置项 auth_config, 此配置项为数组。
  64. }
  65. }
  66. /**
  67. * 检查权限
  68. * @param name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
  69. * @param uid int 认证用户的id
  70. * @param string mode 执行check的模式
  71. * @param relation string 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
  72. * return boolean 通过验证返回true;失败返回false
  73. */
  74. public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or') {
  75. if (!$this->config['auth_on']) {
  76. return true;
  77. }
  78. $authList = $this->getAuthList($uid, $type); //获取用户需要验证的所有有效规则列表
  79. if (is_string($name)) {
  80. $name = strtolower($name);
  81. // if (strpos($name, ',') !== false) {
  82. // $name = explode(',', $name);
  83. // } else {
  84. // $name = [$name];
  85. // }
  86. $name = strpos($name, ',') !== false ? explode(',', $name) : [$name];
  87. }
  88. $list = []; //保存验证通过的规则名
  89. if ($mode == 'url') {
  90. $REQUEST = unserialize(strtolower(serialize($_REQUEST)));
  91. }
  92. foreach ($authList as $auth) {
  93. $query = preg_replace('/^.+\?/U', '', $auth);
  94. if ($mode == 'url' && $query != $auth) {
  95. parse_str($query, $param); //解析规则中的param
  96. $intersect = array_intersect_assoc($REQUEST, $param);
  97. $auth = preg_replace('/\?.*$/U', '', $auth);
  98. if (in_array($auth, $name) && $intersect == $param) { //如果节点相符且url参数满足
  99. $list[] = $auth;
  100. }
  101. } else if (in_array($auth, $name)) {
  102. $list[] = $auth;
  103. }
  104. }
  105. if ($relation == 'or' and ! empty($list)) {
  106. return false;
  107. }
  108. $diff = array_diff($name, $list);
  109. if ($relation == 'and' and empty($diff)) {
  110. return false;
  111. }
  112. return true;
  113. }
  114. /**
  115. * 根据用户id获取用户组,返回值为数组
  116. * @param uid int 用户id
  117. * return array 用户所属的用户组 [
  118. * ['uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
  119. * ...)
  120. */
  121. public function getGroups($uid) {
  122. static $groups = [];
  123. if (isset($groups[$uid])) {
  124. return $groups[$uid];
  125. }
  126. $user_groups = Db::view($this->config['auth_group_access'], 'uid,group_id')->view($this->config['auth_group'], 'title,rules', "{$this->config['auth_group_access']}.group_id={$this->config['auth_group']}.id")
  127. ->where(['uid' => $uid, 'status' => 1])->select();
  128. $groups[$uid] = $user_groups ? $user_groups : [];
  129. return $groups[$uid];
  130. }
  131. /**
  132. * 获得权限列表
  133. * @param integer $uid 用户id
  134. * @param integer $type
  135. */
  136. protected function getAuthList($uid, $type) {
  137. static $_authList = []; //保存用户验证通过的权限列表
  138. $t = implode(',', (array) $type);
  139. if (isset($_authList[$uid . $t])) {
  140. return $_authList[$uid . $t];
  141. }
  142. if ($this->config['auth_type'] == 2 && Session::has('_auth_list_' . $uid . $t)) {
  143. return Session::get('_auth_list_' . $uid . $t);
  144. }
  145. //读取用户所属用户组
  146. $groups = $this->getGroups($uid);
  147. $ids = []; //保存用户所属用户组设置的所有权限规则id
  148. foreach ($groups as $g) {
  149. $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
  150. }
  151. $ids = array_unique($ids);
  152. if (empty($ids)) {
  153. $_authList[$uid . $t] = [];
  154. return [];
  155. }
  156. $map = [
  157. 'id' => ['notin', $ids],
  158. 'type' => $type,
  159. 'status' => 1,
  160. ];
  161. //读取用户组所有权限规则
  162. $rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,name')->select();
  163. //循环规则,判断结果。
  164. $authList = []; //
  165. foreach ($rules as $rule) {
  166. if (!empty($rule['condition'])) { //根据condition进行验证
  167. $this->getUserInfo($uid); //获取用户信息,一维数组
  168. $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
  169. @(eval('$condition=(' . $command . ');'));
  170. $condition && $authList[] = strtolower($rule['name']);
  171. } else {
  172. $authList[] = strtolower($rule['name']); //只要存在就记录
  173. }
  174. }
  175. $_authList[$uid . $t] = $authList;
  176. if ($this->config['auth_type'] == 2) {
  177. $_SESSION['_auth_list_' . $uid . $t] = $authList; //规则列表结果保存到session
  178. }
  179. return array_unique($authList);
  180. }
  181. /**
  182. * 获得用户资料,根据自己的情况读取数据库
  183. */
  184. protected function getUserInfo($uid) {
  185. static $userinfo = [];
  186. if (!isset($userinfo[$uid])) {
  187. $userinfo[$uid] = Db::name($this->config['auth_user'])->where(['uid' => $uid])->find();
  188. }
  189. return $userinfo[$uid];
  190. }
  191. }

相关推荐:

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

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

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

以上就是TP5之Auth权限管理实例的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行