什麼是JWT
JWT 是Json Web Tokens的簡稱。用百度上面的解釋講,是目前流行的跨域認證解決方案,一種基于JSON的、用于在網絡上聲明某種主張的令牌(token)。
JTW原理
jwt驗證方式是将使用者資訊通過加密生成token,每次請求服務端隻需要使用儲存的密鑰驗證token的正确性,不用再儲存任何session資料了,進而服務端變得無狀态,容易實作拓展。

比如加密前的資訊:
{
"username": "vist",
"role": "admin",
"expire": "2020-11-06 15:14:20"
}
加密後:
6gdfg7af816b907f2cc9acbe9c3b4625
JWT 結構
三部分用“.”隔開。如下
edsfdfsdffdssdfR5cCI6IkpXVCJ9.ekgjfdsdfgrMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.Sfdsgdfgsdfgf36POk6yJVfgsd4treh5hdfs
頭部
頭部通常由令牌的類型(typ)和簽名的算法(alg)組成。一般使用base64編碼。
{
"typ": "JWT",
"alg": "HS256"
}
這裡有個點可以說一下,這個typ類型是媒介類型(Media Type),可以認為是媒介類型、媒體類型、裝置類型等等都可以,使用者可以根據令牌類型做不同的操作。舉個例子有個項目是移動端端和PC端。那麼這裡就可以設定typ為移動或PC的。
載荷
載荷是資料的主體部分。一般使用base64編碼。
可以使用JWT官方推薦字段:
iss: 簽發者
sub: 主題
aud: 接收者
exp(expires): 過期時間
iat(issued at): 簽發時間
nbf(not before): 早于某個時間不處理
jti(JWT ID): 唯一辨別
也可以使用自定義字段
{
"username": "vist",
"role": "admin"
}
主體部分可添加非敏感資料
這裡就有個問題了,那什麼是敏感資料。例如:使用者的餘額、使用者的密碼、使用者的隐私資料(女性的年齡)等等都可以是敏感的資料。而非敏感資料則是你可以公開出去的資料。
{
"iss": "我是大哥",
"sub": "審批",
"aud": "牛逼",
"userName": "大哥大",
"approve":"通過",
"iat":"1597000000",
"exp": 1597223455
}
簽名
簽名部分是對前兩部分(頭部,載荷)的簽名,防止資料篡改。
按下列步驟生成:
1、先指定密鑰(secret)
2、把頭部(header)和載荷(payload)資訊分别base64轉換
3、使用頭部(header)指定的算法加密
最終:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), "密鑰/鹽");
通過算法加密後的結果就是簽名。
頭部和載荷都用base64編碼不怕被解碼擷取嗎?
其實不用擔心。因為頭部和載荷的資訊都是非敏感資訊,可以公開的,即使拿到token,也隻能解析出非敏感的資料,并不能拿到敏感資料。
同時篡改頭部或者載荷的資料是不可能通過校驗的。
因為檢驗token的時候會将【頭部.載荷】進行加密然後和簽名比較。而簽名是由 [頭部資料.載荷資料]經過算法加密生成的。也就是說,篡改了就無法通過校驗了。
JWT特點總結
JWT更加簡潔,更适合在HTML和HTTP環境中傳遞。,但更建議JWT建議使用HTTPS協定來傳輸代碼。
JWT适合一次性驗證,如:激活郵件
JWT适合無狀态認證
JWT适合服務端CDN分發内容
相對于資料庫Session查詢更加省時
跨域認證需要做Session共享,而使用了JWT則不需要。因為隻要其他伺服器隻要是使用同一套算法,就可以做資訊的校驗。
JWT預設不加密
使用期間不可取消令牌或更改令牌的權限