簡稱JWT,一個健壯令牌標準-RFC7519。
JWT由三部分組成:php
header
html
payload
laravel
VERIFY SIGNATURE
git
header
&payload
用base64編碼,中間用.
隔開,重要的是VERIFY SIGNATURE
,使用HMAC SHA-256算法生成摘要,具體爲github
#僞代碼 HMACSHA256( base64encode(header) + "." + base64Encode(payload) + '.' +secret )
php中hs256算法:web
//algo指定爲sha256,數據放data,screat爲key string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )
secret
存服務器端,別泄露了。具體瞭解可參考:JWT.io算法
這裏Token生成的算法及驗證就肯定下來,和laravel 5.2
搭配使用以下:apache
1.安裝:composer require tymon/jwt-auth 0.5.*
2.config/app.php
中:json
provider
增長跨域
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class
aliases
增長
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class
3.發佈相應配置文件
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
執行完命令後在config/
下會新增jwt配置文件jwt.php
:
//file:jwt.php /* |-------------------------------------------------------------------------- | JWT Authentication Secret (進行加密算法的時候的secret,這裏32位) |-------------------------------------------------------------------------- */ 'secret' => env('JWT_SECRET', 'ZD23ADFVKSKSDFSDJFKDFDFVsafaa12a'), /* |-------------------------------------------------------------------------- | JWT time to live (token有效期,單位分鐘) |-------------------------------------------------------------------------- | Defaults to 1 hour | 1 hour = 60 minutes */ 'ttl' => 60, /* |-------------------------------------------------------------------------- | Refresh time to live (刷新token時間,單位分鐘) |-------------------------------------------------------------------------- | Defaults to 2 weeks | 2 weeks = 20160 minute */ 'refresh_ttl' => 20160, /* |-------------------------------------------------------------------------- | JWT hashing algorithm (token簽名算法) |-------------------------------------------------------------------------- */ 'algo' => 'HS256', /* |-------------------------------------------------------------------------- | User Model namespace (指向User模型的命名空間路徑) |-------------------------------------------------------------------------- */ 'user' => 'App\Models\User', /* |-------------------------------------------------------------------------- | User identifier (用於從token的sub中獲取用戶) |-------------------------------------------------------------------------- | */ 'identifier' => 'id', /* |-------------------------------------------------------------------------- | Required Claims (必須出如今token的payload中的選項,不然會拋出TokenInvalidException異常) |-------------------------------------------------------------------------- | */ 'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'], /* |-------------------------------------------------------------------------- | Blacklist Enabled (若是該選項被設置爲false,那麼咱們將不能廢止token,即便咱們刷新了token,前一個token仍然有效) |-------------------------------------------------------------------------- */ 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true), /* |-------------------------------------------------------------------------- | Providers (完成各類任務的具體實現,有需求的狀況寫可重寫) |-------------------------------------------------------------------------- */ 'providers' => [ 'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter', 'jwt' => 'Tymon\JWTAuth\Providers\JWT\NamshiAdapter', 'auth' => 'Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter', 'storage' => 'Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter', ], ];
4.最後生成密鑰secret,寫入config/jwt.php
中JWT_SECRET
的value
php artisan jwt:generate
1.控制器中建立token,使用orm獲取用戶對象:
$userObj = User::where('email',$username)->first(); $res['token'] = JWTAuth::fromUser($userObj);
2.客戶端獲取到token,可寫入localstorage
,正常會話週期每次請求帶上,token放入header中:Authorization : Bearer {token}
,這裏的bearer
有持票人的意思,token
兩邊的{}
必須有。
在apache下會有header被丟棄的狀況,apache下得寫配置
RewriteEngine On RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
由於接口多,放到路由羣組用中間件過濾(中間件姿式如使用不正確請指出):
1.執行php artisan make:middleware verifyToken
,在app\Http\Middleware\verifyToken.php
會生成verifyToken前置中間件,填充代碼以下:
namespace App\Http\Middleware; use Closure; use JWTAuth; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenExpiredException; use Tymon\JWTAuth\Exceptions\TokenInvalidException; class verifyToken { /** * 請求前置中間件 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { try { if (!JWTAuth::parseToken()->authenticate()) { return response()->json(['user_not_found'], 404); } } catch (TokenExpiredException $e) { //toke失效,response code可自定義 return response()->json(['token_expired'], 405); } catch (TokenInvalidException $e) { return response()->json(['token_invalid'], $e->getStatusCode()); } catch (JWTException $e) { return response()->json(['token_absent'], $e->getStatusCode()); } return $next($request); } }
2.app\Http\Kernel.php
中在routeMiddleware
處註冊中間件,
'verifyToken' => 'App\Http\Middleware\verifyToken'
3.路由羣組中使用:
//羣組中中間件能夠用多個,用數組傳入便可 //這裏的fetchResponse是後置中間件,用於包裝供cors跨域的幾個header Route::group(['middleware' => ['fetchResponse','verifyToken']],function(){ Route::match(['POST','OPTIONS'],'someDo','someController@someFunc'); })
4.客戶端可根據響應碼不一樣進行處理。完。
參考連接:
1.Github jtw-auth
2.Laravel 5 中使用 JWT(Json Web Token) 實現基於API的用戶認證 - laravel學院
3.JWT安全問題-翻譯 2015年