天天看點

一個小白對thinkphp中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所用的張表如下:<code></code>

<code></code>

<code>//資料庫</code>

<code>/*</code>

<code>-- ----------------------------</code>

<code>-- think_auth_rule,規則表,</code>

<code>-- id:主鍵,name:規則唯一辨別, title:規則中文名稱 status 狀态:為1正常,為0禁用,condition:規則表達式,為空表示存在就驗證,不為空表示按照條件驗證</code>

<code> DROP TABLE IF EXISTS `think_auth_rule`;</code>

<code>CREATE TABLE `think_auth_rule` (  </code>

<code>    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,  </code>

<code>    `name` char(80) NOT NULL DEFAULT '',  </code>

<code>    `title` char(20) NOT NULL DEFAULT '',  </code>

<code>    `type` tinyint(1) NOT NULL DEFAULT '1',    </code>

<code>    `status` tinyint(1) NOT NULL DEFAULT '1',  </code>

<code>    `condition` char(100) NOT NULL DEFAULT '',  # 規則附件條件,滿足附加條件的規則,才認為是有效的規則</code>

<code>    PRIMARY KEY (`id`),  </code>

<code>    UNIQUE KEY `name` (`name`)</code>

<code>) ENGINE=MyISAM  DEFAULT CHARSET=utf8;</code>

<code>-- think_auth_group 使用者組表, </code>

<code>-- id:主鍵, title:使用者組中文名稱, rules:使用者組擁有的規則id, 多個規則","隔開,status 狀态:為1正常,為0禁用</code>

<code> DROP TABLE IF EXISTS `think_auth_group`;</code>

<code>CREATE TABLE `think_auth_group` ( </code>

<code>    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, </code>

<code>    `title` char(100) NOT NULL DEFAULT '', </code>

<code>    `status` tinyint(1) NOT NULL DEFAULT '1', </code>

<code>    `rules` char(80) NOT NULL DEFAULT '', </code>

<code>    PRIMARY KEY (`id`)</code>

<code>-- think_auth_group_access 使用者組明細表</code>

<code>-- uid:使用者id,group_id:使用者組id</code>

<code>DROP TABLE IF EXISTS `think_auth_group_access`;</code>

<code>CREATE TABLE `think_auth_group_access` (  </code>

<code>    `uid` mediumint(8) unsigned NOT NULL,  </code>

<code>    `group_id` mediumint(8) unsigned NOT NULL, </code>

<code>    UNIQUE KEY `uid_group_id` (`uid`,`group_id`),  </code>

<code>    KEY `uid` (`uid`), </code>

<code>    KEY `group_id` (`group_id`)</code>

<code>) ENGINE=MyISAM DEFAULT CHARSET=utf8;</code>

<code> */</code>

<code>複制代碼</code>

<code></code>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}&gt;5 and {score}&lt;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-&gt;check('規則名稱','使用者id')

* 2,可以同時對多條規則進行認證,并設定多條規則的關系(or或者and)

* $auth=new Auth(); $auth-&gt;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}&gt;5 and {score}&lt;100 表示使用者的分數在5-100之間時這條規則才會通過。

*/

有問題的是這一句:

2,可以同時對多條規則進行認證,并設定多條規則的關系(or或者and)

$auth=new Auth(); $auth-&gt;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表名稱的話,隻要配置你的會員表即可。在配置項中增加以下配置項:

<code></code><code></code>

<code> //Auth配置</code>

<code>    'AUTH_CONFIG' =&gt; array(</code>

<code>        // 使用者組資料表名</code>

<code>        //'AUTH_GROUP' =&gt; 'tp_group',</code>

<code>        // 使用者-使用者組關系表</code>

<code>        //'AUTH_GROUP_ACCESS' =&gt; 'tp_group_access',</code>

<code>        // 權限規則表</code>

<code>        //'AUTH_RULE' =&gt; 'tp_rule',</code>

<code>        // 使用者資訊表</code>

<code>        'AUTH_USER' =&gt; 'tp_admin'</code>

<code>    ),</code>

<code> </code>

<code></code>還要補充一點,會員表中會員ID必須為主鍵!

我現在在Home/Login/Index下做實驗:

先聲明Auth類:<code></code><code></code>

<code>&lt;?php</code>

<code>namespace Home\Controller;</code>

<code>class LoginController extends \Think\Controller{</code>

<code>    public function IndexAction(){</code>

<code>        //聲明Auth認證類 </code>

<code>        $auth = new \Think\Auth();</code>

<code>        </code>

<code>        /*</code>

<code>            驗證單個條件</code>

<code>            驗證 會員id 為 1 的 小紅是否有 增加資訊的權限</code>

<code>            </code>

<code>            check方法中的參數解釋:</code>

<code>                參數1:Admin/Article/Add 假設我現在請求 Admin子產品下Article控制器的Add方法</code>

<code>                參數2: 1 為目前請求的會員ID</code>

<code>        */</code>

<code>        var_dump( $auth-&gt;check( 'Admin/Article/Add', 1 ) ); // boolean true</code>

<code>            同時驗證多個條件</code>

<code>            驗證 會員id 為 1 的小紅是否有增加資訊,修改資訊 和一個不存在的規則 的權限</code>

<code>            參數解釋:</code>

<code>                參數1:多條規則同時驗證 , 驗證是否擁有增加、修改、删除的權限</code>

<code>                參數2:目前請求的會員ID   </code>

<code>            ps :XXX是一個不存在的規則為什麼會傳回真呢? 因為check方法 第5個參數預設為 or 也就是說 多個規則中隻要滿足一個條件即為真   </code>

<code>        //var_dump( $auth-&gt;check( 'Admin/Article/Add,Admin/Article/Edit,Admnin/Article/Xxx', 1 ) ); //  boolean true        </code>

<code>            同時驗證多個條件 并且 都為真</code>

<code>            驗證 會員id 為 1 的小紅是否具有 增加 修改 删除 的權限</code>

<code>            參數解釋</code>

<code>                參數1:多條規則同時驗證 ,驗證是否擁有 增加 修改 删除的權限</code>

<code>                參數2:目前請求的會員ID</code>

<code>                參數3:是否用正則驗證condition中的内容</code>

<code>                參數4:</code>

<code>                參數5:必須滿足全部規則才通過 </code>

<code>        //var_dump( $auth-&gt;check( 'Admin/Article/Add,Admin/Article/Edit,Admin/Article/Xxx', 1, 1, '', 'and' ) );        //boolean false     </code>

<code>    }</code>

<code>}</code>

<code>?&gt;</code>

<code></code>Ps:上面的例子是最基本的認證,當然朋友們可以自己定義自己的驗證規則

下面說一下其他例子:

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

在驗證的時候可以用 MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME 來自動擷取目前的 子產品名稱/控制器名稱/方法名稱例如:

$auth-&gt;check( MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME, 1 ) );

本文轉自 IT阿飛 51CTO部落格,原文連結:http://blog.51cto.com/itafei/1961333