[PHP-ZF] Auth + Acl 基礎概念

分類: 技術分享 作者: jaceju

8 4 月 2009

本文轉載自:[PHP-ZF] Auth + Acl 基礎概念

前言

從 Zend Framework 正式推出以來,其認證和權限控制的機制就一直是非常多開發者有興趣的東西。可惜開發手冊上的範例都偏向於介紹單一功能,如果要實際整合到專案時,就會令人不知從何下手。不過在參考了 Rob Allen 的 Getting Started with Zend_Auth 後,算是比較有概念了。

基本上 Zend_Auth 是用來驗證使用者的工具,它可以採用 DbTable 、 Digest 、 HTTP 、 InfoCard 、 LDAP 或是 OpenID 等等驗證方式,這樣一來就能提供給開發者多樣化的選擇。而 Zend_Acl 則是提供了一套非常通用的權限控制系統,讓我們可以簡單地透過使用者的角色去限定他們可以存取的功能。它們可以單獨使用,如果要整合在 Zend Framework 的專案中,則可配合 Controller 的 Plugin 來協同運作。

接下來,我就用我自己的方式來簡單介紹 Zend_Auth 和 Zend_Acl 在做些什麼。

原理

首先,我們來看一個很常見的登入流程。

流程

如果我們要存取一個需要權限的頁面,一般會需要登入才能使用。因此 Zend_Auth 會協助我們判斷使用者是否已經登入。在 Wacow Framework (一套建構在 Zend Framework 上的簡易框架) 裡,這個判斷是寫在 Wacow_Controller_Plugin_Auth::dispatchLoopStartup() 裡面,這樣就能提早改變 $request 物件的 dispatch 內容,讓它執行登入畫面的流程。

使用者驗證

登入畫面實際上是由 UserController::loginAction() 產生,不過瀏覽器的網址列上我們還是會看到剛剛輸入的網址;這是因為我們動態改變了 $request 物件所要 dispatch 的 module 、 controller 及 action 。

在登入畫面中輸入帳號及密碼後,我們可以將 request 送給 loginAction() 本身,然後用 Wacow Action Controller 中的 isPost() 方法來判斷是不是表單內容回送給自己。接著我們可以透過兩種方式來判斷是否有找到對應的使用者:自行處理驗證方式或是透過上述 Zend_Auth 所提供多種驗證方式來驗證使用者。

自行處理驗證方式這部份程式碼的話,自由度比較大,適合用在客戶要求的登入程序比較複雜的系統。而使用 Zend_Auth 的驗證機制時,則會提供以下數種結果讓我們參考:

Zend_Auth_Result::SUCCESS
Zend_Auth_Result::FAILURE
Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
Zend_Auth_Result::FAILURE_UNCATEGORIZED

一般只要判斷 SUCCESS 狀態即可,其他都是驗證失敗。

在驗證成功後,我們可以透過 Zend_Auth 所提供的 Storage 物件來存放使用者資料,最常用的 Storage 就是 Session 。接著我們就可以在 loginAction() 中,將頁面導回原來的要存取的網址;如果是使用 Ajax 來輸入帳號密碼,那麼成功後也可以用 location.reload() 的方式直接重載頁面即可。

權限判斷

Zend_Acl 需要註冊「資源 (resource) 」和「角色 (role) 」這兩種物件,然後再利用 allow() 及 deny() 兩個方法來建構整個存取控制清單 (ACL, Access Controll List) 。所以系統一開始就會先將 ACL 透過 Zend_Acl 設定好。

所以回到原來的網址時,因為這時我們已經登入並取得該帳號的角色了,因此就可以利用存取清單來判斷我們是不是能存取這個頁面;如果可以就執行該頁面,不行的話就改變 $request 物件的 dispatch 內容,讓它導向顯示「權限不足」的畫面。

一般來說, ACL 可以從資料庫取得,也可以寫死在繼承自 Zend_Acl 的類別中。如果從資料庫取得的話,除了使用者資料表外,我們會需要以下其他幾個資料表:角色 (roles) 、資源 (resources) 及權限 (permissions) ;其中權限資料表記錄的就是角色與資源的對應關係。

感想

先前我在開發 Zend Framework 專案時,都是參考別人寫的程式碼。雖然可以照抄後稍加修改,但有時還是不甚瞭解為什麼要這樣做。像 Zend_Auth 和 Zend_Acl 都是寫完程式很久後,才慢慢瞭解它們運作上的觀念。希望這次將 Zend_Auth 和 Zend_Acl 運作的觀念整理出來,能對剛入門的朋友有些許的幫助。

我要留言

關於這裡

這個部落格分享了哇寶在電子商務領域的技術及資訊,希望能讓更多人一起為台灣的網路產業加油。