Laravel 的 API 認證系統 Passport 三部曲(1、passport安裝+配置)php
Laravel 的 API 認證系統 Passportcss
請求令牌
建立密碼受權的客戶端後,就能夠經過向用戶的電子郵件地址和密碼向 /oauth/token 路由發出 POST 請求來獲取訪問令牌。而該路由已經由 Passport::routes 方法註冊,所以不須要手動定義它。若是請求成功,會在服務端返回的 JSON 響應中收到一個 access_token 和 refresh_token:laravel
$http = new GuzzleHttp\Client; $response = $http->post('http://your-app.com/oauth/token', [ 'form_params' => [ 'grant_type' => 'password', 'client_id' => 'client-id', 'client_secret' => 'client-secret', 'username' => 'taylor@laravel.com', 'password' => 'my-password', 'scope' => '', ], ]); return json_decode((string) $response->getBody(), true);
在你的應用程序發佈我的訪問令牌以前,你須要在 passport:client 命令後帶上 --personal 參數來建立對應的客戶端。若是你已經運行了 passport:install 命令,則無需再運行此命令:json
php artisan passport:client --personal
建立我的訪問客戶端後,你可使用 User 模型實例上的 createToken 方法來爲給定用戶發佈令牌。
createToken 方法接受令牌的名稱做爲其第一個參數和可選的 做用域 數組做爲其第二個參數:api
$user = App\User::find(1); // Creating a token without scopes... $token = $user->createToken('Token Name')->accessToken; // Creating a token with scopes... $token = $user->createToken('My Token', ['place-orders'])->accessToken;
注意: 因爲passport默認只能夠走一個guard認證,當多平臺的時候,可使用auth2.0來輔助操做,首先使用Auth2.0驗證該平臺對應的guard(固然,驅動使用session))下其帳號密碼是否正確,驗證經過以後再獲取該用戶實例並給予私人訪問令牌,這樣就作到了不一樣平臺的令牌生成)數組
經過中間件session
Passport 包含一個 驗證保護機制 能夠驗證請求中傳入的訪問令牌。配置 api 的看守器使用 passport 驅動程序後,只須要在須要有效訪問令牌的任何路由上指定 auth:api 中間件:app
Route::get('/user', function () { // })->middleware('auth:api');
咱們實現方式ide
因爲passport只能夠走api一個guard驗證,也就是隻能夠走一個用戶受權表,這裏咱們多平臺多登錄受權表則只用上面的驗證登錄確定就不對了,如上所說咱們結合auth2.0來進行分平臺進行驗證。工具
eg:
public function handle($request, Closure $next, $guard = null) { if (empty(Auth::guard($guard)->user())) { return response()->json(["message" => "Unauthenticated."], 401); } return $next($request); }
protected $routeMiddleware = [
'apiAuth' => ApiAuth::class,
......
];
註銷登陸
eg:
/** * 登出程序操做. * * @return \Illuminate\Http\Response */ public function logout() { $user = $this->guard()->user(); if (empty($user)) { return $this->sendError('暫未登陸', ['暫未登陸'], 403); } // 獲取當前登錄用戶的access_token的id $accessToken = $user->access_token; // 找到這條access_token而且將其刪除 $token = Token::find($accessToken); if (empty($token)) { return $this->sendError('暫無有效令牌', ['暫無有效令牌'], 403); } if (!empty($token->delete())) { return $this->sendResponse([], '退出成功!'); } else { return $this->sendError('退出失敗', ['退出失敗'], 500); } }
按期檢查過時token(官方文檔沒給,我的作的優化)
建立token生成事件的監聽器來處理該用戶當前客戶端下的全部失效的token
在「/app/Providers/EventServiceProvider.php」中的「$listen」數組中添加
// 生成token,檢查失效的進行刪除 'Laravel\Passport\Events\AccessTokenCreated' => [ 'App\Listeners\RevokeOldTokens', ],
終端執行:
php artisan event:generate
提示:"Events and listeners generated successfully!"表明建立成功了
執行刪除失效token操做
在 'App\Listeners\RevokeOldTokens'的handle方法中執行刪除失效token操做
Token::where('id', '!=', $event->tokenId) ->where('user_id', $event->userId) ->where('client_id', $event->clientId) ->where('expires_at', '<', Carbon::now()) ->orWhere('revoked', true) ->delete();