本文实例讲述了thinkPHP5框架auth权限控制类。分享给大家供大家参考,具体如下:
这个是比较简单的用法:
直接把类贴出来,这里我改了,我没有用uid,因为我建的表是admin表,所以代码里对应查询改成了aid
还有表名,我都去掉了前缀
<?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> // +----------------------------------------------------------------------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 string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组 * @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 = hinkDb::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 = hinkDb::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]= hinkDb::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 authAuth(); $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程序设计有所帮助。