初見JWT,不知所雲,趕緊Google(百度)一下,原來是跨域身份驗證解決方案。
JWT只是縮寫,全拼則是 JSON Web Tokens ,是目前流行的跨域認證解決方案,一種基於JSON的、用於在網絡上聲明某種主張的令牌(token)。
JWT 原理
jwt驗證方式是將用戶信息通過加密生成token,每次請求服務端只需要使用保存的密鑰驗證token的正確性,不用再保存任何session數據了,進而服務端變得無狀態,容易實現拓展。
加密前的用戶信息,如:
{
"username": "vist", "role": "admin", "expire": "2018-12-08 20:20:20" }
客戶端收到的token:
7cd357af816b907f2cc9acbe9c3b4625
JWT 結構
一個token分為3部分:
- 頭部(header)
- 載荷(payload)
- 簽名(signature)
3個部分用“.”分隔,如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
頭部
JWT的頭部分是一個JSON對象,描述元數據,通常是:
{
"typ": "JWT", "alg": "HS256" }
- typ 為聲明類型,指定 "JWT"
- alg 為加密的算法,默認是 "HS256"
也可以是下列中的算法:
JWS | 算法名稱 | 描述 |
---|---|---|
HS256 | HMAC256 | HMAC with SHA-256 |
HS384 | HMAC384 | HMAC with SHA-384 |
HS512 | HMAC512 | HMAC with SHA-512 |
RS256 | RSA256 | RSASSA-PKCS1-v1_5 with SHA-256 |
RS384 | RSA384 | RSASSA-PKCS1-v1_5 with SHA-384 |
RS512 | RSA512 | RSASSA-PKCS1-v1_5 with SHA-512 |
ES256 | ECDSA256 | ECDSA with curve P-256 and SHA-256 |
ES384 | ECDSA384 | ECDSA with curve P-384 and SHA-384 |
ES512 | ECDSA512 | ECDSA with curve P-521 and SHA-512 |
載荷
載荷(payload)是數據的載體,用來存放實際需要傳遞的數據信息,也是一個JSON對象。
JWT官方推薦字段:
- iss: jwt簽發者
- sub: jwt所面向的用戶
- aud: 接收jwt的一方
- exp: jwt的過期時間,這個過期時間必須要大於簽發時間
- nbf: 定義在什么時間之前,該jwt都是不可用的.
- iat: jwt的簽發時間
- jti: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
也可以使用自定義字段,如:
{
"username": "vist", "role": "admin" }
簽名
簽名部分是對前兩部分(頭部,載荷)的簽名,防止數據篡改。
按下列步驟生成:
1、先指定密鑰(secret)
2、把頭部(header)和載荷(payload)信息分別base64轉換
3、使用頭部(header)指定的算法加密
最終,簽名(signature) = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)
客戶端得到的簽名:
header.payload.signature
也可以對JWT進行再加密。
JWT 使用
1、服務端根據用戶登錄狀態,將用戶信息加密到token中,返給客戶端
2、客戶端收到服務端返回的token,存儲在cookie中
3、客戶端和服務端每次通信都帶上token,可以放在http請求頭信息中,如:Authorization字段里面
4、服務端解密token,驗證內容,完成相應邏輯
JWT 特點
- JWT更加簡潔,更適合在HTML和HTTP環境中傳遞
- JWT適合一次性驗證,如:激活郵件
- JWT適合無狀態認證
- JWT適合服務端CDN分發內容
- 相對於數據庫Session查詢更加省時
- JWT默認不加密
- 使用期間不可取消令牌或更改令牌的權限
- JWT建議使用HTTPS協議來傳輸代碼