本文實(shí)例講述了thinkPHP5框架auth權(quán)限控制類。分享給大家供大家參考,具體如下:
這個(gè)是比較簡(jiǎn)單的用法:
直接把類貼出來,這里我改了,我沒有用uid,因?yàn)槲医ǖ谋硎莂dmin表,所以代碼里對(duì)應(yīng)查詢改成了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; /** * 權(quán)限認(rèn)證類 * 功能特性: * 1,是對(duì)規(guī)則進(jìn)行認(rèn)證,不是對(duì)節(jié)點(diǎn)進(jìn)行認(rèn)證。用戶可以把節(jié)點(diǎn)當(dāng)作規(guī)則名稱實(shí)現(xiàn)對(duì)節(jié)點(diǎn)進(jìn)行認(rèn)證。 * $auth=new Auth(); $auth->check('規(guī)則名稱','用戶id') * 2,可以同時(shí)對(duì)多條規(guī)則進(jìn)行認(rèn)證,并設(shè)置多條規(guī)則的關(guān)系(or或者and) * $auth=new Auth(); $auth->check('規(guī)則1,規(guī)則2','用戶id','and') * 第三個(gè)參數(shù)為and時(shí)表示,用戶需要同時(shí)具有規(guī)則1和規(guī)則2的權(quán)限。 當(dāng)?shù)谌齻€(gè)參數(shù)為or時(shí),表示用戶值需要具備其中一個(gè)條件即可。默認(rèn)為or * 3,一個(gè)用戶可以屬于多個(gè)用戶組(think_auth_group_access表 定義了用戶所屬用戶組)。我們需要設(shè)置每個(gè)用戶組擁有哪些規(guī)則(think_auth_group 定義了用戶組權(quán)限) * * 4,支持規(guī)則表達(dá)式。 * 在think_auth_rule 表中定義一條規(guī)則時(shí),如果type為1, condition字段就可以定義規(guī)則表達(dá)式。 如定義{score}>5 and {score}<100 表示用戶的分?jǐn)?shù)在5-100之間時(shí)這條規(guī)則才會(huì)通過。 */ //數(shù)據(jù)庫(kù) /* -- ---------------------------- -- think_auth_rule,規(guī)則表, -- id:主鍵,name:規(guī)則唯一標(biāo)識(shí)(就是常見的路由列表,如:admin/index/index), title:規(guī)則中文名稱,例如添加商品 status 狀態(tài):為1正常,為0禁用,condition:規(guī)則表達(dá)式,為空表示存在就驗(yàn)證,不為空表示按照條件驗(yàn)證 -- ---------------------------- 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 '', # 規(guī)則附件條件,滿足附加條件的規(guī)則,才認(rèn)為是有效的規(guī)則 PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ---------------------------- -- auth_group 用戶組表, -- id:主鍵, title:用戶組中文名稱, rules:用戶組擁有的規(guī)則id, 多個(gè)規(guī)則","隔開,status 狀態(tài):為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 用戶組明細(xì)表 -- 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{ //默認(rèn)配置 protected $_config = array( 'auth_on' => true, // 認(rèn)證開關(guān) 'auth_type' => 1, // 認(rèn)證方式,1為實(shí)時(shí)認(rèn)證;2為登錄認(rèn)證。 'auth_group' => 'auth_group', // 用戶組數(shù)據(jù)表名 'auth_group_access' => 'group_access', // 用戶-用戶組關(guān)系表 'auth_rule' => 'auth_rule', // 權(quán)限規(guī)則表 'auth_user' => 'admin' // 用戶信息表 ); public function __construct() { if (config('auth_config')) { //可設(shè)置配置項(xiàng) auth_config, 此配置項(xiàng)為數(shù)組。 $this->_config = array_merge($this->_config, config('auth_config')); } } /** * 檢查權(quán)限 * @param name string|array 需要驗(yàn)證的規(guī)則列表,支持逗號(hào)分隔的權(quán)限規(guī)則或索引數(shù)組 * @param uid int 認(rèn)證用戶的id * @param string mode 執(zhí)行check的模式 * @param relation string 如果為 'or' 表示滿足任一條規(guī)則即通過驗(yàn)證;如果為 'and'則表示需滿足所有規(guī)則才能通過驗(yàn)證 * @return boolean 通過驗(yàn)證返回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); //獲取用戶需要驗(yàn)證的所有有效規(guī)則列表 if (is_string($name)) { $name = strtolower($name); if (strpos($name, ',') !== false) { $name = explode(',', $name); } else { $name = array($name); } } $list = array(); //保存驗(yàn)證通過的規(guī)則名 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); //解析規(guī)則中的param $intersect = array_intersect_assoc($REQUEST,$param); $auth = preg_replace('/\?.*$/U','',$auth); if ( in_array($auth,$name) && $intersect==$param ) { //如果節(jié)點(diǎn)相符且url參數(shù)滿足 $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; } /** * 根據(jù)用戶id獲取用戶組,返回值為數(shù)組 * @param uid int 用戶id * @return array 用戶所屬的用戶組 array( * array('uid'=>'用戶id','group_id'=>'用戶組id','title'=>'用戶組名稱','rules'=>'用戶組擁有的規(guī)則id,多個(gè),號(hào)隔開'), * ...) */ 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]; } /** * 獲得權(quán)限列表 * @param integer $uid 用戶id * @param integer $type */ protected function getAuthList($uid,$type) { static $_authList = array(); //保存用戶驗(yàn)證通過的權(quán)限列表 $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();//保存用戶所屬用戶組設(shè)置的所有權(quán)限規(guī)則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, ); //讀取用戶組所有權(quán)限規(guī)則 $rules = \think\Db::name($this->_config['auth_rule'])->where($map)->field('condition,name')->select(); //循環(huán)規(guī)則,判斷結(jié)果。 $authList = array(); // foreach ($rules as $rule) { if (!empty($rule['condition'])) { //根據(jù)condition進(jìn)行驗(yàn)證 $user = $this->getUserInfo($uid);//獲取用戶信息,一維數(shù)組 $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){ //規(guī)則列表結(jié)果保存到session $_SESSION['_auth_list_'.$uid.$t]=$authList; } return array_unique($authList); } /** * 獲得用戶資料,根據(jù)自己的情況讀取數(shù)據(jù)庫(kù) */ 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
然后在使用的控制器中使用構(gòu)造方法,或者繼承一個(gè)使用了構(gòu)造方法的控制器,構(gòu)造方法如下:
public function _initialize() { $aid = 1; $auth = new \auth\Auth(); $request = Request::instance(); $au = $auth->check($request->module() . '/' . $request->controller() . '/' . $request->action(), $aid); if (!$au) {// 第一個(gè)參數(shù)是規(guī)則名稱,第二個(gè)參數(shù)是用戶UID /* return array('status'=>'error','msg'=>'有權(quán)限!');*/ $this->error('你沒有權(quán)限'); } }
上面的$aid應(yīng)該是用戶登錄以后獲取的,正常情況下應(yīng)該是session()
獲取的用戶id
相關(guān)業(yè)務(wù)邏輯可以自行判斷,剩下的就是添加全縣,用戶組添加啊,等等系列增刪改查了。
希望本文所述對(duì)大家基于ThinkPHP框架的PHP程序設(shè)計(jì)有所幫助。