最近的一個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
而後修改boostrap/app.php
文件,添加以下配置數據庫
修改路由文件routers/web.php
bootstrap
必定要使用jwt.auth
中間件,而後在Controllers
目錄下新建App/AuthController.php
文件,文件內容以下:segmentfault
修改app/Exceptions/Handler.php
文件瀏覽器
而後瀏覽器訪問域名/auth/home
,結果以下:app
那麼如今從源碼看一下401是怎麼來的?composer
這裏定義了這個路由,要通過
jwt.auth
這個中間件,下一步這個中間件在哪裏定義的呢,ide
能夠看到在
LumenServiceProvider
中有$this->app->routeMiddleware($this->middlewareAlias)
這麼一句,
能夠看到在這裏是定義了一個名爲
jwt.auth
的路由中間件,對應Tymon\JWTAuth\Http\Middleware\Authenticate
這個類,看一下這個類的實現
能夠看到是經過
$this->authenticate
這個方法進行驗證的,那麼如今看下這個方法的實現
能夠看到這裏有兩個方法,
checkForToken
用來驗證是否存在token,若是不存在則拋出異常,若是存在則進入$this->auth->parseToken()->authenticate()
用來驗證token是否合法,怎麼驗證token是否存在這裏不作討論,咱們來看下他是怎麼驗證token是否合法的,跟蹤代碼發現執行的事JWTAuth
類的下面方法
能夠看到首先從payload中得到id值,而後經過id檢索用戶,若是檢索成功,返回false,token不合法,不然返回檢索到的用戶,token合法,那麼跟蹤一下檢索用戶的代碼,最終進入的是
JWTGuard
類的以下方法
$this->provider
就是咱們在config/auth.php
中配置的
eloquent,對應的類是
EloquentUserProvider
,咱們看下它的retrieveById
方法,實現以下
這裏就已經在從數據庫中查找用戶,在實際研發中對於數據庫的查找咱們可能有本身的邏輯,那麼咱們只能去實現咱們本身的Provider而後去替換掉
JWTGuard
中的Provider,那麼這一步該怎麼作呢?
在bootstrap/app.php
有這麼一句$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
,咱們能夠看下LumenServiceProvider的源碼,
能夠看到有這麼一個方法,咱們能夠去看下他的實現,
能夠看到這裏傳入了Provider,那麼咱們看一下AuthManager的createUserProvider方法
程序會先去讀取Provider的配置信息,也就是auth.php中的
這麼一部分,而後判斷
customProviderCreators
中是否存在對應的Guard
的驅動,若是存在則根據驅動建立用戶自定義Provider,不然判斷driver
是否爲datebase或者eloquent,若是也不成立則拋出異常,不然建立DatebaseProvider或者EloquentProvider,那麼根據這麼一段代碼,咱們只須要在auth.php配置好本身的驅動,而後將咱們本身的Provider實現類注入到customProviderCreators
去就能夠了,那麼怎麼注入呢,在AuthManager
中有這麼一個方法
至此如何自定義
Provider
就解決了,如今就來實戰一下,自定義的Provider代碼以下,
參照
EloquentUserProvider
和DatebaseUserProvider
可知須要實現UserProvider
接口,爲了方便,我就直接繼承DatebaseUserProvider
了,重寫了retrieveById
方法,默認返回true,首先修改auth.php中的provider的driver
爲my
,而後就是注入MyJWTUserProvider
了,在app/Jwt目錄下新建一個MyLumenServiceProvider
,代碼以下
最後將
boostrap/app.php
中register的LumenServiceProvider
改成MyLumenServiceProvider
至此JWT還剩下一個生成用戶驗證返回token的過程