thinkPHP5框架auth权限控制类与用法示例
2018-09-07 12:26
本文实例讲述了thinkPHP5框架auth权限控制类。分享给大家供大家参考,具体如下:
这个是比较简单的用法:
直接把类贴出来,这里我改了,我没有用uid,因为我建的表是admin表,所以代码里对应查询改成了aid
还有表名,我都去掉了前缀
<?php // +---------------------------------------------------------------------- // ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // Copyright (c) 2011 // +---------------------------------------------------------------------- namespace auth; /** * 权限认证类 * 功能特性: * 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:规则唯一标识(就是常见的路由列表,如:admin/index/index), title:规则中文名称,例如添加商品 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证 -- ---------------------------- DROP TABLE IF EXISTS `auth_rule`; CREATE TABLE `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; -- ---------------------------- -- auth_group 用户组表, -- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则,隔开,status 状态:为1正常,为0禁用 -- ---------------------------- DROP TABLE IF EXISTS `auth_group`; CREATE TABLE `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; -- ---------------------------- -- group_access 用户组明细表 -- uid:用户id,group_id:用户组id -- ---------------------------- DROP TABLE IF EXISTS `group_access`; CREATE TABLE `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( auth_on => true, // 认证开关 auth_type => 1, // 认证方式,1为实时认证;2为登录认证。 auth_group => auth_group, // 用户组数据表名 auth_group_access => group_access, // 用户-用户组关系表 auth_rule => auth_rule, // 权限规则表 auth_user => admin // 用户信息表 ); public function __construct() { if (config(auth_config)) { //可设置配置项 auth_config, 此配置项为数组。 $this->_config = array_merge($this->_config, config(auth_config)); } } /** * 检查权限 * @param name stringarray 需要验证的规则列表,支持逗号分隔的权限规则或索引数组 * @param uid int 认证用户的id * @param string mode 执行check的模式 * @param relation string 如果为 or 表示满足任一条规则即通过验证;如果为 and则表示需满足所有规则才能通过验证 * @return boolean 通过验证返回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 = array($name); } } $list = array(); //保存验证通过的规则名 if ($mode==url) { $REQUEST = unserialize( strtolower(serialize($_REQUEST)) ); } foreach ( $authList as $auth ) { $query = preg_replace(/^.+\?/U,,$auth); if ($mode==url && $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 ($relation == or and !empty($list)) { return true; } $diff = array_diff($name, $list); if ($relation == and and 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 = array(); if (isset($groups[$uid])) return $groups[$uid]; $user_groups = \think\Db::name($this->_config[auth_group_access]) ->alias(a) ->join($this->_config[auth_group]. g, g.id=a.group_id) ->where(a.aid=$uid and g.status=1) ->field(aid,group_id,title,rules)->select(); $groups[$uid] = $user_groups ? $user_groups : array(); return $groups[$uid]; } /** * 获得权限列表 * @param integer $uid 用户id * @param integer $type */ protected function getAuthList($uid,$type) { static $_authList = array(); //保存用户验证通过的权限列表 $t = implode(,,(array)$type); if (isset($_authList[$uid.$t])) { return $_authList[$uid.$t]; } if( $this->_config[auth_type]==2 && isset($_SESSION[_auth_list_.$uid.$t])){ return $_SESSION[_auth_list_.$uid.$t]; } //读取用户所属用户组 $groups = $this->getGroups($uid); $ids = array();//保存用户所属用户组设置的所有权限规则id foreach ($groups as $g) { $ids = array_merge($ids, explode(,, trim($g[rules], ,))); } $ids = array_unique($ids); if (empty($ids)) { $_authList[$uid.$t] = array(); return array(); } $map=array( id=>array(in,$ids), type=>$type, status=>1, ); //读取用户组所有权限规则 $rules = \think\Db::name($this->_config[auth_rule])->where($map)->field(condition,name)->select(); //循环规则,判断结果。 $authList = array(); // 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]); } } $_authList[$uid.$t] = $authList; if($this->_config[auth_type]==2){ //规则列表结果保存到session $_SESSION[_auth_list_.$uid.$t]=$authList; } return array_unique($authList); } /** * 获得用户资料,根据自己的情况读取数据库 */ protected function getUserInfo($uid) { static $userinfo=array(); if(!isset($userinfo[$uid])){ $userinfo[$uid]=\think\Db::name($this->_config[auth_user])->where(array(aid=>$uid))->find(); } return $userinfo[$uid]; } }
Auth.php放在extend下面的auth目录里,命名空间为auth
然后在使用的控制器中使用构造方法,或者继承一个使用了构造方法的控制器,构造方法如下:
public function _initialize() { $aid = 1; $auth = new \auth\Auth(); $request = Request::instance(); $au = $auth->check($request->module() . / . $request->controller() . / . $request->action(), $aid); if (!$au) {// 第一个参数是规则名称,第二个参数是用户UID /* return array(status=>error,msg=>有权限!);*/ $this->error(你没有权限); } }
上面的$aid应该是用户登录以后获取的,正常情况下应该是session()获取的用户id
相关业务逻辑可以自行判断,剩下的就是添加全县,用户组添加啊,等等系列增删改查了。
更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI(CodeIgniter)框架进阶教程》、《Zend FrameWork框架入门教程》及《PHP模板技术总结》。
希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。