老司機帶你領悟 Laravel 之授權系統

Dennis_Ritchie發表於2019-12-26

前言

Laravel之授權

這篇博文主要是帶大家瞭解laravel的授權系統,依照慣例,我會忽略一些細節,大家自己有興趣的話,自行閱讀。如果你仔細閱讀了我之前寫的,我覺得讀懂這篇博文,簡直不要太容易。

準備

在閱讀這篇部落格之前,你一定要閱讀《老司機帶你深入理解 Laravel 之 Facade》,這是必須的。

Auth Facade

我們的分析從Illuminate\Support\Facades\Auth開始,下面是它的定義:

Laravel之授權

我們搜尋整個laravel專案,搜尋關鍵詞'Auth',在Illuminate\Auth\AuthServiceProvider中可以看到:

Laravel之授權

這裡給Auth註冊了一個單例,也就是說所有對Illuminate\Support\Facades\Auth的操作實際上就是在操作Illuminate\Auth\AuthManager類的例項物件,下面我以Auth::guard()方法給大家分析,大家應該操作過這個方法吧。

Laravel之授權

這裡的getDefaultDriver返回預設的驅動,我們來看看:

Laravel之授權

這裡直接讀取app/auth.php檔案的defaults下的guard,開啟我的配置檔案,可以看到:

Laravel之授權

返回到guard方法中,繼續呼叫resolve方法,如下:

Laravel之授權

這裡的getConfig方法會讀取到下面的配置:

Laravel之授權

返回到resolve方法中:

Laravel之授權

從這裡的分析可以看到createSessionDriver方法被呼叫
Laravel之授權

首先這裡的createUserProvider方法被呼叫,它的$config['provider']為users,我們來看一下這個方法:

Laravel之授權

這裡的$config就是:

Laravel之授權

因為drivereloquent,所以這裡會呼叫createEloquentProvider方法:

Laravel之授權

也就是說createEloquentProvider方法返回了一個\Illuminate\Auth\EloquentUserProvider類的物件,我們再次回到createSessionDriver方法中:

Laravel之授權

這裡建立了一個SessionGuard類的物件,至此resolve方法解析完畢,返回到guard方法中,如果你需要驗證這一點的話,你可以在任何一個控制器中,執行dd(Auth::guard())會返回一個SessionGuard類的物件。

當我們授權使用者的時候,我們會使用到如下所示的程式碼:

/*** 
@var  $guard SessionGuard
* **/
$guard = Auth::guest();
$guard->attempt(["name"=>"DennisRitche","password"=>"Goodbyte World"]);

根據上面的分析,SessionGuard類的attempt方法被呼叫:

Laravel之授權

這裡的provider就是我們之前建立的Illuminate\Auth\EloquentUserProvider類物件,我們看下它的retrieveByCredentials方法:

Laravel之授權

上面的createModel實際上就是建立一個我們之前配置的類的物件:

Laravel之授權

retrieveByCredentials方法根據我們的使用者名稱從資料庫查詢出對應的記錄,返回到SessionGuard類的attempt
方法中,繼續呼叫如下程式碼:

Laravel之授權

方法hasValidCredentials作用就是驗證我們提交的密碼是否和資料庫裡面的密碼是相等(資料庫裡面的密碼加密過,所以在比較之前,使用者提交的密碼也需要經過加密步驟),這部分程式碼很簡單,這裡略過,如果hasValidCredentials返回true,表示驗證通過,此時login方法被呼叫:

Laravel之授權

首先呼叫updateSession方法會把當前登陸的使用者標識寫入到session中:

Laravel之授權

接下來呼叫setUser方法,如下:

Laravel之授權

這裡記錄了當前登入的使用者,以後每次Auth::user()呼叫都會獲取到這個使用者例項。

總結

上面簡要的分析了Laravel的授權系統,程式碼本身並不複雜,我也是給大家介紹了一下分析的思路,很多細節,需要自己去分析和理解。我有一個QQ群,有興趣的可以加一下:

如果有不懂的地方,可以加我的qq:1174332406,或者是微信:itshardjs

相關文章