laravel搭建passport

安裝#

安裝 Passport#

1.在你的 Shell 中執(zhí)行以下命令

composerrequirelaravel/passport

如果你使用的 Laravel 版本是 5.5 以下,你需要手動在config/app.php文件 providers 數(shù)組中加入如下代碼

Laravel\Passport\PassportServiceProvider::class,

2.運行遷移文件

在你的 Shell 中執(zhí)行如下命令

php artisan migrate

Passport 服務(wù)提供器使用框架注冊自己的遷移目錄,因此在注冊服務(wù)后,你可以直接運行php artisan migrate來為 Passport 生成所需的數(shù)據(jù)表

3.生成加密密鑰

在你的 Shell 中執(zhí)行如下命令

php artisan passport:install

此命令會創(chuàng)建生成安全訪問令牌時所需的加密密鑰,同時,這條命令也會創(chuàng)建用于生成訪問令牌的「個人訪問」客戶端和「密碼授權(quán)」。

4.添加 Trait

將 Laravel\Passport\HasApiTokens Trait 添加到 App\User 模型中


5.注冊路由

在 AuthServiceProvider 的 boot 方法中調(diào)用 Passport::routes 函數(shù)。

classAuthServiceProviderextendsServiceProvider{publicfunctionboot(){$this->registerPolicies();Passport::routes();}}

如果你的程序是需要前后端分離形式的OAuth認(rèn)證而不是多平臺認(rèn)證那么你可以在routers()方法中傳遞一個匿名函數(shù)來自定定義自己需要注冊的路由,我這里是前后端分離的認(rèn)證形式,因此我只需要對我的前端一個Client提供Auth的認(rèn)證,所以我只注冊了獲取Token的路由,同時我還為它自定義了前綴名。

Passport::routes(function(RouteRegistrar$router){$router->forAccessTokens();},['prefix'=>'api/oauth']);

6.更改看守器驅(qū)動

將配置文件 config/auth.php 中授權(quán)看守器 guards 的 api 的 driver 選項改為 passport。此調(diào)整會讓你的應(yīng)用程序在在驗證傳入的 API 的請求時使用 Passport 的 TokenGuard 來處理

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

至此 Passport 已經(jīng)安裝完成,剩下的文檔里所講到的前端部分的話,由于我是只需要使用它做 Auth 的認(rèn)證,并不需要實現(xiàn)完整的 OAuth 功能,所以我們完全可以不使用前端頁面。

使用#

為了 Api 返回數(shù)據(jù)方便,我封裝了幾個函數(shù)

functionrespond($status,$respond){returnresponse()->json(['status'=>$status,is_string($respond)?'message':'data'=>$respond]);}functionsucceed($respond='Request success!'){returnrespond(true,$respond);}functionfailed($respond='Request failed!'){returnrespond(false,$respond);}

respond 函數(shù)可以做基本返回,succeed 和 failed 是在 respond 函數(shù)上做的再次封裝,用以返回請求成功和請求失敗數(shù)據(jù)。

然后我們需要使用一層代理。

先說一下使用代理的原因,Passport 認(rèn)證的流程是 從屬應(yīng)用帶著 主應(yīng)用

生成的 Client Token 和 用戶輸入的賬號密碼去請求主應(yīng)用的 Passport Token 路由,以獲得 access token (訪問令牌) 和 refresh token (刷新令牌),然后帶著得到的 access token 就可以訪問 auth:api 下的路由了。但是我們并沒有從屬應(yīng)用,是由前后端分離的前端來請求這個token,如果從前端想來拉取這個 access token 就需要把 Client token 寫死在前端里,這樣是很不合理的,所以我們可以在內(nèi)部寫一個代理,由應(yīng)用自身帶著 Client token 去請求自身以獲取 access token,這樣說可能有一點繞,大概請求過程是下面這個樣子

1.前端帶著用戶輸入的賬號密碼請求服務(wù)端2.服務(wù)端帶著從前端接收到賬號與密碼,并在其中添加 Client_id 與 Client_token,然后帶著這些參數(shù)請求自身的 Passport 認(rèn)證路由,然后返回認(rèn)證后的 Access token 與 refresh token

下面是代碼實現(xiàn),我在 App\Http\Controllers\Traits 下新建了一個 ProxyHelpers 的 Trait,當(dāng)然,這個函數(shù)是我根據(jù)我的業(yè)務(wù)邏輯自己封裝的,如果不適合你的業(yè)務(wù)邏輯你可以自行調(diào)整。

root().'/api/oauth/token';$params=array_merge(config('passport.proxy'),['username'=>request('email'),'password'=>request('password'),]);$respond=$client->request('POST',$url,['form_params'=>$params]);}catch(RequestException$exception){thrownewUnauthorizedException('請求失敗,服務(wù)器錯誤');}if($respond->getStatusCode()!==401){returnjson_decode($respond->getBody()->getContents(),true);}thrownewUnauthorizedException('賬號或密碼錯誤');}}

config/passport.php內(nèi)容如下

['grant_type'=>env('OAUTH_GRANT_TYPE'),'client_id'=>env('OAUTH_CLIENT_ID'),'client_secret'=>env('OAUTH_CLIENT_SECRET'),'scope'=>env('OAUTH_SCOPE','*'),],];

env 文件內(nèi)容如下

OAUTH_GRANT_TYPE=passwordOAUTH_CLIENT_ID=2OAUTH_CLIENT_SECRET=2HaTQJF33Sx98HjcKDiSVWZjrhVYGgkHGP8XLG1OOAUTH_SCOPE=*

我們需要用到的 client token 是 id 為 2 的 client token,不要搞錯了喲~

然后我們只需要在控制器中 use 這個 Trait,然后調(diào)用$this->authenticate()就可以得到認(rèn)證成功的 token,如果請求失敗的話,你可以使用catch來捕捉錯誤拋出異常。

publicfunctionlogin(Request$request){$needs=$this->validate($request,rules('login'));$user=User::where('email',$needs['email'])->first();if(!$user){thrownewUnauthorizedException('此用戶不存在');}$tokens=$this->authenticate();returnsucceed(['token'=>$tokens,'user'=>newUserResource($user)]);}

得到的 tokens 返回如以下格式

{"token_type":"Bearer","expires_in":31536000,"access_token":"token_str","refresh_token":"token_str"}

做完這一切后你就可以在前端向這樣子請求服務(wù)端了

axios.post('yourdomain/login',login_form).then(resource=>{})

如果請求成功,那么你將會得到 用戶的信息和 access token,refresh token。

然后在你的前端 http 請求 header 里需要加入一個參數(shù)Authorization

axios.defaults.headers.common['Authorization']=token.token_type+' '+token.access_token

然后在你需要使用到 auth 認(rèn)證的路由里使用中間件auth:api,一切就大功告成啦~

轉(zhuǎn)自Seaony

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容