JWT - Json Web Token

JWT是基於Json的開放標準,其定義了安全、緊湊、自包含的信息交換協議php

優勢

  • 跨平臺、跨域、輕量級的傳輸
  • 可用於無狀態的 身份認證、信息交換
  • JWT中的載荷信息是可信的(由於簽名的存在)
  • 普遍用於分佈式系統的SSO單點登陸
  • OAUTH2中引入JWT能極大的簡化認證流程
    • 受權服務器不須要維護Token存儲
    • 資源服務器也沒必要要求Token檢查
    • 減小了服務間的HTTP通訊

缺點

  • JWT中存儲信息若是過多很容易形成Token過大(可經過jti換取Redis集中存儲中的用戶信息 解決該問題)

組成

JWT由如下三部分Json數據的Base64Url密文,點號拼接而成算法

  1. Headers:包括ALGORITHM、TOKEN TYPE
  2. PAYLOAD:數據載荷,包括了三類claim信息
    • Reserved claims預約義信息(包括iss簽發者exp過時時間sub請求者aud接收者nbf起效時間iat簽發時間jti惟一標識
    • Public claims自定義信息
    • Private claims訂閱方和接受方的協議信息
  3. Signature:簽名(可選HS256(對稱加密)RS256(非對稱加密)兩種簽名算法)
HMACSHA256(  #HS256簽名算法
		base64UrlEncode(header) + "." + base64UrlEncode(payload),
		secret
	)

使用

HTTP頭部帶上Token信息apache

Authorization: Bearer jwt_token

Apache配置

Apache默認丟棄結構特殊、非base64編碼的Authorization頭部,因此須要額外配置下跨域

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

Laravel JWT-Auth

## 安裝 ##
composer require tymon/jwt-auth:0.5.*
#註冊
Tymon\JWTAuth\Providers\JWTAuthServiceProvider
'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth'
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory'
#發佈配置
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
#生成祕鑰
php artisan jwt:generate

## 配置 ##
- secret  簽名祕鑰
- ttl  token生存時間/min
- refresh_ttl  token刷新生存時間/min
- algo  token簽名算法(維持默認便可)
- user  User模型名字空間
- identifier  對應於token subject claim的User模型標識
- required_claims  token中必須攜帶的chaim
- blacklist_enabled  若爲false則刷新令牌後老令牌仍是不會失效

## 簽發令牌 ##
# 1. 快捷簽發 #
$customClaims = [...]  #儘可能控制chaim信息量以防token過大
$token = JWTAuth::attempt($credentials [, $customClaims])  #嘗試登錄並簽發令牌
$token = JWTAuth::fromUser($user [, $customClaims])  #基於用戶簽發令牌
# 2. 底層自定義簽發 #
$payload = JWTFactory::make($customClaims)
$payload = JWTFactory::sub(xxx)->aud(xxx)->foo($customClaims)->make()
$token = JWTAuth::encode($payload)

## 認證 ##
# 1. 客戶端請求提供token #
- HTTP頭部方式:Authorization: Bearer JWT_Token
- Query方式:?token=JWT_Token
# 2. 解析請求中的token #
$token = JWTAuth::getToken()
$user = JWTAuth::parseToken()->authenticate()
JWTAuth::setToken('xxx.yyy.zzz') #手動設置一個jwt

## 中間件 ##
protected $routeMiddleware = [
    ...
    'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
    'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
];
1. GetUserFromToken中間件 檢查並解析token,不然拋出異常
	- tymon.jwt.absent
	- tymon.jwt.expired
	- tymon.jwt.invalid
	- tymon.jwt.user_not_found
	- tymon.jwt.valid
2. RefreshToken中間件  每次請求刷新token
相關文章
相關標籤/搜索