一、JWT概述:
(1)token 只是一種思路,一種解決用戶授權問題的思考方式,基於這種思路,針對不同的場景可以有很多種的實現。
而在眾多的實現中,JWT (JSON Web Token) 的實現最為流行.JWT 這個標准提供了一系列如何創建具體 token 的方法,
這些緣故方法和規范可以讓我們創建 token 的過程變得更加合理和效率.
(2),JWT是一個字符串,我們在發起網絡請求時,將其放在header或者url中,這樣可以保證傳遞的數據被篡改時能被我們發現,保證安全性。
1. 使用 composer 安裝
composer require tymon/jwt-auth 1.*@rc
2.1 發布配置文件
# 這條命令會在 config 下增加一個 jwt.php 的配置文件 php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
2.2 生成加密密鑰
php artisan jwt:secret
2.3 更新你的模型
如果你使用默認的 User 表來生成 token,你需要在該模型下增加一段代碼
<?php namespace App; use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements JWTSubject # 這里別忘了加 { use Notifiable; // Rest omitted for brevity /** * Get the identifier that will be stored in the subject claim of the JWT. * * @return mixed */ public function getJWTIdentifier() { return $this->getKey(); } /** * Return a key value array, containing any custom claims to be added to the JWT. * * @return array */ public function getJWTCustomClaims() { return []; } }
2.4 注冊兩個 Facade
這兩個 Facade 並不是必須的,但是使用它們會給你的代碼編寫帶來一點便利。
config/app.php
'aliases' => [ ... // 添加以下兩行 'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth', 'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory', ],
如果你不使用這兩個 Facade,你可以使用輔助函數 auth ()
auth () 是一個輔助函數,返回一個 guard,暫時可以看成 Auth Facade。
// 如果你不用 Facade,你可以這么寫 auth('api')->refresh(); // 用 JWTAuth Facade JWTAuth::parseToken()->refresh();
2.5 修改 auth.php
config/auth.php
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', // 原來是 token 改成jwt 'provider' => 'users', ], ],
2.6 注冊一些路由
注意:在 Laravel 下,route/api.php
中的路由默認都有前綴 api
。
Route::group([ 'prefix' => 'auth' ], function ($router) { Route::post('login', 'AuthController@login'); Route::post('logout', 'AuthController@logout'); Route::post('refresh', 'AuthController@refresh'); Route::post('me', 'AuthController@me'); });
2.7 創建 token 控制器
php artisan make:controller AuthController
AuthController
值得注意的是 Laravel 這要用 auth('api')
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; class AuthController extends Controller { /** * Create a new AuthController instance. * 要求附帶email和password(數據來源users表) * * @return void */ public function __construct() { // 這里額外注意了:官方文檔樣例中只除外了『login』 // 這樣的結果是,token 只能在有效期以內進行刷新,過期無法刷新 // 如果把 refresh 也放進去,token 即使過期但仍在刷新期以內也可刷新 // 不過刷新一次作廢 $this->middleware('auth:api', ['except' => ['login']]); // 另外關於上面的中間件,官方文檔寫的是『auth:api』 // 但是我推薦用 『jwt.auth』,效果是一樣的,但是有更加豐富的報錯信息返回 } /** * Get a JWT via given credentials. * * @return \Illuminate\Http\JsonResponse */ public function login() { $credentials = request(['email', 'password']); if (! $token = auth('api')->attempt($credentials)) { return response()->json(['error' => 'Unauthorized'], 401); } return $this->respondWithToken($token); } /** * Get the authenticated User. * * @return \Illuminate\Http\JsonResponse */ public function me() { return response()->json(auth('api')->user()); } /** * Log the user out (Invalidate the token). * * @return \Illuminate\Http\JsonResponse */ public function logout() { auth('api')->logout(); return response()->json(['message' => 'Successfully logged out']); } /** * Refresh a token. * 刷新token,如果開啟黑名單,以前的token便會失效。 * 值得注意的是用上面的getToken再獲取一次Token並不算做刷新,兩次獲得的Token是並行的,即兩個都可用。 * @return \Illuminate\Http\JsonResponse */ public function refresh() { return $this->respondWithToken(auth('api')->refresh()); } /** * Get the token array structure. * * @param string $token * * @return \Illuminate\Http\JsonResponse */ protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => auth('api')->factory()->getTTL() * 60 ]); } }