Lumen用戶認證JWT,源碼解讀

最近的一個PHP項目,上一個項目是採用ThinkPHP來弄的,由於很早就據說過Laravel的大名,因此進了Laravel的官網,意外發現了Lumen,正好我項目是提供API的,因此選擇了Lumen,由於是Laravel的精簡版,看了幾天的Laravel文檔,也總結出了本身的一些經驗,不權威:
一、Larave的核心是服務容器,服務容器的主要功能是依賴注入
二、Laravel的各部分功能以組件形式提供,須要什麼注入什麼
下面進入正題JWT認證,感謝學習 Lumen 用戶認證 (二) —— 使用 jwt-auth 插件這篇文章對個人幫助。php

如何作用戶認證?
根據Laravel文檔描述,Laravel提供用戶認證的接口,他的核心是看守器(Guard)提供器(Provider),看守器定義怎麼認證用戶,提供器定義怎麼檢索用戶。laravel

首先建立項目lumen new jwt-demo,而後進入jwt-demo目錄,執行composer require tymon/jwt-auth:1.0.0-rc.2,在項目根目錄下建立config文件夾,並將vender/laravel中的auth.php拷貝到config目錄下,auth.php文件內容以下:web

clipboard.png

而後修改boostrap/app.php文件,添加以下配置數據庫

clipboard.png

修改路由文件routers/web.phpbootstrap

clipboard.png

必定要使用jwt.auth中間件,而後在Controllers目錄下新建App/AuthController.php文件,文件內容以下:segmentfault

clipboard.png

修改app/Exceptions/Handler.php文件瀏覽器

clipboard.png

而後瀏覽器訪問域名/auth/home,結果以下:app

clipboard.png


那麼如今從源碼看一下401是怎麼來的?composer

clipboard.png

這裏定義了這個路由,要通過jwt.auth這個中間件,下一步這個中間件在哪裏定義的呢,ide

clipboard.png

能夠看到在LumenServiceProvider中有$this->app->routeMiddleware($this->middlewareAlias)這麼一句,

clipboard.png

能夠看到在這裏是定義了一個名爲jwt.auth的路由中間件,對應Tymon\JWTAuth\Http\Middleware\Authenticate這個類,看一下這個類的實現

clipboard.png

能夠看到是經過$this->authenticate這個方法進行驗證的,那麼如今看下這個方法的實現

clipboard.png

能夠看到這裏有兩個方法,checkForToken用來驗證是否存在token,若是不存在則拋出異常,若是存在則進入$this->auth->parseToken()->authenticate()用來驗證token是否合法,怎麼驗證token是否存在這裏不作討論,咱們來看下他是怎麼驗證token是否合法的,跟蹤代碼發現執行的事JWTAuth類的下面方法

clipboard.png

能夠看到首先從payload中得到id值,而後經過id檢索用戶,若是檢索成功,返回false,token不合法,不然返回檢索到的用戶,token合法,那麼跟蹤一下檢索用戶的代碼,最終進入的是JWTGuard類的以下方法

clipboard.png

$this->provider就是咱們在config/auth.php中配置的

clipboard.png

eloquent,對應的類是EloquentUserProvider,咱們看下它的retrieveById方法,實現以下

clipboard.png

這裏就已經在從數據庫中查找用戶,在實際研發中對於數據庫的查找咱們可能有本身的邏輯,那麼咱們只能去實現咱們本身的Provider而後去替換掉JWTGuard中的Provider,那麼這一步該怎麼作呢?
bootstrap/app.php有這麼一句$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);,咱們能夠看下LumenServiceProvider的源碼,

clipboard.png

能夠看到有這麼一個方法,咱們能夠去看下他的實現,

clipboard.png

能夠看到這裏傳入了Provider,那麼咱們看一下AuthManager的createUserProvider方法

clipboard.png

程序會先去讀取Provider的配置信息,也就是auth.php中的

clipboard.png

這麼一部分,而後判斷customProviderCreators中是否存在對應的Guard的驅動,若是存在則根據驅動建立用戶自定義Provider,不然判斷driver是否爲datebase或者eloquent,若是也不成立則拋出異常,不然建立DatebaseProvider或者EloquentProvider,那麼根據這麼一段代碼,咱們只須要在auth.php配置好本身的驅動,而後將咱們本身的Provider實現類注入到customProviderCreators去就能夠了,那麼怎麼注入呢,在AuthManager中有這麼一個方法

clipboard.png

至此如何自定義Provider就解決了,如今就來實戰一下,自定義的Provider代碼以下,

clipboard.png

參照EloquentUserProviderDatebaseUserProvider可知須要實現UserProvider接口,爲了方便,我就直接繼承DatebaseUserProvider了,重寫了retrieveById方法,默認返回true,首先修改auth.php中的provider的drivermy,而後就是注入MyJWTUserProvider了,在app/Jwt目錄下新建一個MyLumenServiceProvider,代碼以下

clipboard.png

最後將boostrap/app.php中register的LumenServiceProvider改成MyLumenServiceProvider

至此JWT還剩下一個生成用戶驗證返回token的過程

相關文章
相關標籤/搜索