什么是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默認不加密
使用期間不可取消令牌或更改令牌的權限