一個小白對auth的理解

第一次發教程有不足的地方希望兄弟們多多包涵!

PS:最近需要做一個驗證用戶權限的功能,在官方和百度看了下,發現大家都是用auth來做驗證,官方有很多auth的使用教程,但是都不全面,我也提問了幾個關於auth的問題 也沒人來回答我,無奈只好一步步看代碼研究了。本人基礎不好,屬於半路出家的那種,希望我的教程大家不要見笑。 新手純屬無奈之舉。。。
廢話不多開始解密:

首先說下我使用的Thinkphp版本:ThinkPHP3.2.3完整版
auth 翻譯成中文就是認證的意思。
TP的auth類 核心版 是沒有的。完整版纔有,這點大家要注意下!
1:首先打開Auth.class.php
文件位置 Thinkphp/Library/Think/Auth.class.php
2:打開Auth類文件之後我們要建Auth認證所需要的3張表了,Auth類中已經給了表所用的字段了 直接複製回來粘貼到 phpmyadmin中運行sql就可以;
Auth所用的張表如下:
  1. //數據庫
  2. /*
  3. -- ----------------------------
  4. -- think_auth_rule,規則表,
  5. -- id:主鍵,name:規則唯一標識, title:規則中文名稱 status 狀態:爲1正常,爲0禁用,condition:規則表達式,爲空表示存在就驗證,不爲空表示按照條件驗證
  6. -- ----------------------------
  7.  DROP TABLE IF EXISTS `think_auth_rule`;
  8. CREATE TABLE `think_auth_rule` (  
  9.     `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,  
  10.     `name` char(80) NOT NULL DEFAULT '',  
  11.     `title` char(20) NOT NULL DEFAULT '',  
  12.     `type` tinyint(1) NOT NULL DEFAULT '1',    
  13.     `status` tinyint(1) NOT NULL DEFAULT '1',  
  14.     `condition` char(100) NOT NULL DEFAULT '',  # 規則附件條件,滿足附加條件的規則,才認爲是有效的規則
  15.     PRIMARY KEY (`id`),  
  16.     UNIQUE KEY `name` (`name`)
  17. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  18. -- ----------------------------
  19. -- think_auth_group 用戶組表, 
  20. -- id:主鍵, title:用戶組中文名稱, rules:用戶組擁有的規則id, 多個規則","隔開,status 狀態:爲1正常,爲0禁用
  21. -- ----------------------------
  22.  DROP TABLE IF EXISTS `think_auth_group`;
  23. CREATE TABLE `think_auth_group` ( 
  24.     `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
  25.     `title` char(100) NOT NULL DEFAULT '', 
  26.     `status` tinyint(1) NOT NULL DEFAULT '1', 
  27.     `rules` char(80) NOT NULL DEFAULT '', 
  28.     PRIMARY KEY (`id`)
  29. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  30. -- ----------------------------
  31. -- think_auth_group_access 用戶組明細表
  32. -- uid:用戶id,group_id:用戶組id
  33. -- ----------------------------
  34. DROP TABLE IF EXISTS `think_auth_group_access`;
  35. CREATE TABLE `think_auth_group_access` (  
  36.     `uid` mediumint(8) unsigned NOT NULL,  
  37.     `group_id` mediumint(8) unsigned NOT NULL, 
  38.     UNIQUE KEY `uid_group_id` (`uid`,`group_id`),  
  39.     KEY `uid` (`uid`), 
  40.     KEY `group_id` (`group_id`)
  41. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  42.  */
複製代碼
PS:大家自行改成自己所需的表前綴即可;
另外要說的一點是:這3張表 大家可以可以改表名,只要字段包含Auth所需的認證字段也可以。如果你把這3張表改名了,只要在Auth的配置項中改成自己對應的表名即可。

3:3張表建好 先講下這3張表的作用 (本人理解有限 大家勿噴)
(我的表前綴爲tp_)
tp_auth_rule(rule翻譯成中文爲【規則】 合起來就是認證規則)
字段概述:
id:這個不必多說 相信大家都懂得 (表主鍵,自增 ,規則ID標識)
name:認證規則 (字段保存的是你需要認證的 【模塊名/控制器名/方法名】或【自定義規則】 字符串類型 這裏大家最好按照 模塊名/控制器/方法 來填寫,多個規則之間用,隔開即可,當前規則是按照你的思路來定製的,你也可以填寫一個 admin 或 * 或 guanliyuan 等!字段長度爲80,不要超過這個長度就可以)
title:規則描述 這個不多講
type:tinyint類型的,如果type爲1, condition字段就可以定義規則表達式。 如定義{score}>5 and {score}<100 表示用戶的分數在5-100之間時這條規則纔會通過。(默認爲1)
condition:當type爲1時,condition字段裏面的內容將會用作正則表達式的規則來配合認證規則來認證用戶
tp_auth_group(group翻譯爲中文爲 【組】的意思,合起來就是認證組)
字段概述:
id:這個大家都懂得吧(認證組的ID標識,表主鍵 自增)
title:認證組名稱
status:是否開啓 0爲關閉 1爲開啓 (默認爲1 開啓)
rules :規則ID (這裏填寫的是 tp_auth_rule裏面的規則的ID,下面會給大家演示)
tp_auth_group_access(這個表就倆字段,是規則和組別的中間表)
字段概述:
uid:會員ID (這裏填寫是 需要認證的會員ID)
group_id:認證組ID (這裏填寫的是 認證組的ID)

Ps:這裏跟大家說下我是怎麼理解這3張表的關係的:
實際上使用Auth是需要4張表的(1.會員表 2.認證規則表 3.認證組表 4.認證中間表),我表達能力不強,簡單的說下:

a.我在 tp_auth_rule裏面添加一個或多個驗證規則用來驗證你的訪問權限
例如:
(Admin/Article/Add)增加文章的權限
(Admin/Article/Edit)修改文章的權限
(Admin/Article/Delete)刪除文章的權限
Ps:這3個規則可以合併成一個規則,合併成一個規則的話就是: (Admin/Article/Add,Admin/Article/Edit,Admin/Article/Delete)!
還有一點:這個規則是80個字節,大家不要超過了; 這個規則你也可以寫成 Article (意思就是擁有所有操作文章的權限)
也可以寫成(Article-Add-Edit-Delete)這樣的 意思是擁有文章的增刪改權限
還可以寫成(Article-Add-Edit)扎樣的 意思是 擁有文章的增加和修改的權限,沒有刪除權限
總之這裏的規則你可以按照自己的思路來,很靈活的。這點超級贊!
//爲了更多的小白明白我在囉嗦囉嗦:
例如:
Home/List/Php 擁有訪問前臺Php欄目的權限
Home/List/HTML 擁有訪問前臺HTML欄目的權限
Home/List/PHP,Home/List/HTML 擁有訪問前臺 PHP 和 HTML 欄目的權限
LIST-PHP-HTML 擁有訪問前臺PHP 和 HTML 欄目的權限
總之規則大家自定義 很靈活,只要在你需要認證的地方靈活的運用Auth驗證就可以的!

b.在認證組中 添加2個用戶組(分別是:信息錄入部門、信息審覈部門,信息XX部門)
status 默認爲就行,默認爲1 就是開啓這個認證組
rules 規則ID多個規則用,隔開 例如我現在有4條規則分別是:
id爲1: Admin/Article/Add 增加文章的權限
id爲2: Admin/Article/Edit 修改文章的權限
id爲3: Admin/Article/Delete 刪除文章的權限
id爲4: Article-Add-Edit-Delete 擁有文章的增刪改權限
分析下:信息錄入部 需要的是 文章的 增加和修改還有刪除權限,審覈部門需要的是 修改和刪除的權限 ,信息xx部門需要所有操作信息的權限
根據分析 :
信息錄入部門的 rules需要的規則爲: 1,2,3
信息審覈部門需要的是:2,3
信息XX部門需要的是 4
好了,插入數據:
信息錄入部: title:信息錄入部 rules:1,2,3 (插入之後假設ID爲1)
信息審覈部: title:信息審覈部 rules: 2,3 (插入之後建設ID爲2)
信息XX部 : title:信息XX部 rules:4 (插入之後建設ID爲3)
c.認證中間表中錄入需要認證的會員ID和認證組ID即可
ps:假設我現在有會員表爲tp_user
裏面有4個會員分別是:
id爲1的: 小紅
id爲2的: 小明
id爲3的: 小張
id爲4的: 小李

下面分配權限:
小紅和小明是信息錄入部門的:
那麼tp_auth_access如下:
uid爲 1 的小紅 所屬認證部爲 1(1也就是認證組表中的信息錄入部門,擁有增加、修改、刪除的權限)
uid爲 2 的小明 同小紅一個級別(功能一樣)
uid爲 3 的小張 所屬認證部爲 2 (2也就是認證組表中的信息審覈部,擁有修改、刪除的權限)
uid爲 4 的小李 所屬認證部爲 3 (3也就是認證表中的信息XX部 擁有信息的 增加、修改、刪除的權限)
PS:可能我說的有點繞,但是意思差不多就這樣 嘿嘿! rule表中爲所有需要認證的規則條件,group表爲部門組,部門的權限爲規則表中的規則id,access表爲記錄用戶屬於那個部門的! 這樣理解了麼?

4:現在開始認證權限吧:

Ps:這裏我要糾正一點:我現在用的Thinkphp版本爲ThinkPHP3.2.3完整版:在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之間時這條規則纔會通過。
*/

有問題的是這一句:
2,可以同時對多條規則進行認證,並設置多條規則的關係(or或者and)
$auth=new Auth(); $auth->check('規則1,規則2','用戶id','and');
問題:
Auth類中的check方法一共有 5 個參數
public function check($name, $uid, $type=1, $mode='url', $relation='or')
所以官方類中的 第三個參數填寫and視距上是不起任何作用的!
不知道是不是這樣 哈!。。。。


Ps:在使用auth之前,要先配置下auth所用的配置項:
如果你沒修改auth_rule,auth_group,auth_group_access表名稱的話,只要配置你的會員表即可。在配置項中增加以下配置項:

  1.  //Auth配置
  2.     'AUTH_CONFIG' => array(
  3.         // 用戶組數據表名
  4.         //'AUTH_GROUP' => 'tp_group',
  5.         // 用戶-用戶組關係表
  6.         //'AUTH_GROUP_ACCESS' => 'tp_group_access',
  7.         // 權限規則表
  8.         //'AUTH_RULE' => 'tp_rule',
  9.         // 用戶信息表
  10.         'AUTH_USER' => 'tp_admin'
  11.     ),
  12.  
複製代碼
還要補充一點,會員表中會員ID必須爲主鍵!


我現在在Home/Login/Index下做實驗:
先聲明Auth類:
  1. <?php
  2. namespace Home\Controller;
  3. class LoginController extends \Think\Controller{
  4.     public function IndexAction(){

  5.         //聲明Auth認證類 
  6.         $auth = new \Think\Auth();
  7.         
  8.         /*
  9.             驗證單個條件
  10.             驗證 會員id 爲 1 的 小紅是否有 增加信息的權限
  11.             
  12.             check方法中的參數解釋:
  13.                 參數1:Admin/Article/Add 假設我現在請求 Admin模塊下Article控制器的Add方法
  14.                 參數2: 1 爲當前請求的會員ID
  15.         */
  16.         var_dump( $auth->check( 'Admin/Article/Add', 1 ) ); // boolean true

  17.         
  18.         /*
  19.             同時驗證多個條件
  20.             驗證 會員id 爲 1 的小紅是否有增加信息,修改信息 和一個不存在的規則 的權限
  21.             
  22.             參數解釋:
  23.                 參數1:多條規則同時驗證 , 驗證是否擁有增加、修改、刪除的權限
  24.                 參數2:當前請求的會員ID   

  25.             ps :XXX是一個不存在的規則爲什麼會返回真呢? 因爲check方法 第5個參數默認爲 or 也就是說 多個規則中只要滿足一個條件即爲真   
  26.         */
  27.         //var_dump( $auth->check( 'Admin/Article/Add,Admin/Article/Edit,Admnin/Article/Xxx', 1 ) ); //  boolean true        

  28.         /*
  29.             同時驗證多個條件 並且 都爲真
  30.             驗證 會員id 爲 1 的小紅是否具有 增加 修改 刪除 的權限

  31.             參數解釋
  32.                 參數1:多條規則同時驗證 ,驗證是否擁有 增加 修改 刪除的權限
  33.                 參數2:當前請求的會員ID
  34.                 參數3:是否用正則驗證condition中的內容
  35.                 參數4:
  36.                 參數5:必須滿足全部規則才通過 
  37.         */
  38.         //var_dump( $auth->check( 'Admin/Article/Add,Admin/Article/Edit,Admin/Article/Xxx', 1, 1, '', 'and' ) );        //boolean false     
  39.     }
  40. }
  41. ?>
複製代碼
Ps:上面的例子是最基本的認證,當然朋友們可以自己定義自己的驗證規則

下面說一下其他例子:

rule規則表中的name可以寫 *** 或者 admin 或其他字符來代替一個通用驗證規則;

在驗證的時候可以用 MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME 來自動獲取當前的 模塊名稱/控制器名稱/方法名稱例如:
$auth->check( MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME, 1 ) );



/*
還有一些我沒了解的使用方法:
例如:

*/
  1. if ($mode=='url' && $query!=$auth ) {
  2.     parse_str($query,$param); //解析規則中的param
  3.     $intersect = array_intersect_assoc($REQUEST,$param);
  4.     $auth = preg_replace('/\?.*$/U','',$auth);
  5.     if ( in_array($auth,$name) && $intersect==$param ) {  //如果節點相符且url參數滿足
  6.         $list[] = $auth ;
  7.     }
  8. }
複製代碼
這裏的$query!=$anth 不知道怎麼用這個,我本地測試的時候在rule規則中增加了一個規則是 test?aa=1&bb=2
在使用auth的時候這樣用可以通過認證:

url中get或者POST必須有這個aa=1&bb=2纔會驗證成功,很迷糊這裏到底是怎麼個情況,有了解的大神希望告知下
$auth->check( 'test' , 1 );

*難道這個 query!=auth 是爲了不支持pathinfo的 ?module=home&controller=user&action=login 驗證這樣的?搞不懂。。。*





Ps:你可以寫一個公共方法,把auth認證寫到方法裏面 方便調用!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章