Lumen Auth、Guard、User 身份驗證詳解(二)- 你的架構不是你的架構

Wake Liu
興趣使然的程式猿
6 min readAug 7, 2019
Lumen Auth、Guard、User 身份驗證詳解 文章目錄:(一)Authentication 文件忙什麼
(二)你的架構不是你的架構
(三)全部的流程都解開了!(上)

Lumen 的身份驗證機制其實不複雜,但又無法簡單就看個明白,只因為它背負著 Laravel 的子系統 這個原罪,從文件到程式內容內容都經過了大幅簡化 — 簡化到你不回頭去看 Laravel 的程式碼根本猜不出他的全貌(例如 Lumen 的 config/auth.php 和 Lavarel 的 config/auth.php)。

身為直接接觸 Lumen 而非經由 Laravel 的開發者,遇到問題或想要新增某些功能,會採取的行動不外乎是 找官方文件 → 找網路資料 → 爬梳原始碼,結果官方文件寫的不清不楚,網路資料一團模糊,爬梳原始碼又因為抽象層和程式碼資訊不足(相較於 Laravel 而言)使得整件事情困難重重,要耗費許多額外力氣才能整理歸納出整個架構。

這也是為什麼我會寫這一系列文,希望能幫其他純 Lumen 開發者更快速的掌握全貌,少走一點冤枉路。

設定檔之謎

要瞭解 Lumen 當中的身份驗證管理,從設定檔開始是個好切入點,不過我們要看的是 Laravel 的 config/auth.php,這份和 Lumen 下的檔案在選項和參數上幾乎一致,卻提供了更齊全的資訊。

啟用身份驗證時的預設項目

'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],

設定檔中第一個區塊定義了系統預設的 Guard 名為 web,以及預設的密碼重設模組 users (密碼部份不在這系列文章討論之列)。

Guard 設定內容

'guards' => [  'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],

下一個區塊是實際註冊 Guard 的部份,預設共有兩個:

  1. 名稱為 web 的 Guard,由 session driver 驅動 SessionGuard 進行實際運作,使用者物件提供者是 users 模組。
  2. 名稱為 api 的 Guard,由 token driver 驅動 TokenGuard 進行實際運作,使用者物件提供者是 users 模組。

使用者物件提供模組

'providers' => [  'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],

再下一個區塊註冊的是 使用者物件提供模組,包含被註解掉的共有兩種:

  1. 名為 users,由 eloquent driver 驅動 Eloquent 進行實際運作的模組。
  2. 或由 database driver 驅動 Database 直連進行實際運作的模組。

至於 driver 下方的其他設定(例如 modeltable )都是針對各 driver 的客製參數,可以先忽略不看。

回到 Lumen

看完了 Laravel 下的設定檔,再回頭看 Lumen 的 config/auth.php 的內容:

'defaults' => [
'guard' => env ('AUTH_GUARD', 'api'),
],

'guards' => [
'api' => ['driver' => 'api'],
],

'providers' => [
//
],

是不是真的有夠精簡?

比起 Laravel 只多了一個從 .env 檔案中取得 Guard 指派的函式(並預設使用名為 api的 Guard)。

要特別注意的是, 雖然 Lumen 設定了 'driver' => 'api',但實際上系統內並沒有 ApiGuard 這種東西, api driver 所驅動的是基於 RequestGuard 的 微客製版本 。有點複雜對嗎?沒關係,我們會在後面一一說明。

小結

從兩份設定檔中,我們可以概略瞭解到一些角色的存在,包括:

  • Named Guard:名為 xxx 的 Guard,包含 driver 和 provider 兩部份。
  • Guard Driver:實際 Guard 的驅動器。
  • Named Provider:名為 xxx 的 Provider(User Provider),包含 driver 和其他參數。
  • Provider Driver:實際 User Provider 的驅動器。

基本身份驗證架構

從上一段設定檔的說明和整理中,我們可以繪製出像這樣的關係圖。

當一個 XXX Guard 被設定和啟用時,它會透過一組 GuardDriver 去驅動某個 Guard,並在該 Guard 當中進行身份查驗等相關動作,此外 XXX Guard 本身也會定義一組 XXX Provider,同時藉由指定的 ProviderDriver 去驅動某個 UserProvider。

那麼這個 XXX Guard 是怎麼在架構中被使用的呢?我來幫忙把前後兩個關鍵角色補到圖上。

實際上 Lumen 是透過 AuthManager 來取得可用的 Guard + User 組合進行身份驗證等判斷;而有哪些 Guard / User 可用,則是 被定義且規範在 config/auth.php 中。所以當你要新增自訂的 Guard / Driver / Provider,一定要記得在設定檔補上對應的設定,系統才能正常使用這些自定義的部份。

結語

到這邊為止完整的架構脈落幾乎已經出來了,關於架構下的物件實務是怎麼進行的,流程細節又是怎麼運作的,我們會在下一篇文章深入這些角色和介面型別。謝謝各位的閱讀。

--

--