JSON Web Token(JWT)是一個開放的標準(RFC 7519),它定義了一個緊湊且自包含的方式,用於在各方之間作為 JSON 對象安全地傳輸信息。由於此信息是經過數字簽名的,因此可以被驗證和信任。
今天我們就來簡單的認識一下 JSON Web Token。
JWT 認證和 session認證的區別
首先需要說明 JSON Web Token 是可以用於認證的,那麼就先來對比一下 JSON Web Token 認證和 傳統的 session 認證的區別,傳統的 session 認證是有狀態的,也就是說我們需要在服務端保存用戶的認證信息,如果服務端重新或者換一臺服務器,那麼這個認證就失效了,並且傳統的 session 的認證方式擴展起來不是那麼的容易。
基於 JSON Web Token 的鑑權機制類似於 http 協議,是一種無狀態的,服務器不需要保存用戶的認證信息或者會話信息,這也就意味著 JWT 認證機制的應用不需要去考慮用戶在哪一臺服務器登錄了,這就為應用的擴展提供了便利,也是由於這個特性,JWT 在微服務架構中應用廣泛。
JSON Web Token 的組成
一個 JSON Web Token 實際上就是一個字符串,它由三部分組成:**頭部、載荷與簽名**,如下圖所示:

1、頭部(header )
頭部用於描述關於該 JSON Web Token 的最基本的信息,例如其類型以及簽名所用的算法等,通常如下所示:
{
"alg": "HS256",
"typ": "JWT"
}
- alg屬性:表示簽名使用的算法,默認為HMAC SHA256(寫為HS256)
- typ屬性:表示令牌的類型,JWT令牌統一寫為JWT
頭部一般使用 base64 加密,加密後密文:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2、載荷(payload)
載荷是 JSON Web Token 的主體內容部分,裡面存放一些有效信息,JSON Web Token 標準定義中定義了以下 5 個字段:
- iss: 該JWT的簽發者
- sub: 該JWT所面向的用戶
- aud: 接收該JWT的一方
- exp(expires): 什麼時候過期,這裡是一個Unix時間戳
- iat(issued at): 在什麼時候簽發的
除了標準定義中的字段外,我們還可以自定義字段,比如在 JWT 中,我們的載荷信息可能如下:
{
"sub": "1234567890",
"name": "pingtouge",
"admin": true
}
我們需要注意,在默認情況下 JWT 是未加密的,每一個人都可以讀取其內容,因此在載荷中,不要存放私密信息,防止信息洩露。
3、簽名(signature)

簽名是 JSON Web Token 中比較重要的一部分,前面兩部分都是使用 Base64 進行編碼的,signature 需要使用編碼後的 header 和 payload 以及我們提供的一個密鑰,然後使用 header 中指定的簽名算法(HS256)進行簽名,簽名的作用是保證 JWT 沒有被篡改過。
為什麼需要簽名?
對於加密算法來說,碰撞概率還是比較小的,一般而言,不同的輸入加密後的輸出是不一樣的,不同輸入產生相同結果的概率還是相當小的,所以可以利用加密算法的這個特性來判斷 JWT 是否被篡改過。
假如有人篡改了載荷中的信息,再進行編碼的話,那麼新的頭部和載荷的簽名跟之前的簽名是不一樣的,並且如何加密的密鑰不一樣的話,得出來的簽名結果也會不一樣。
JWT使用場景
- Authentication(鑑權)
這是使用JWT最常見的情況。 一旦用戶登錄,每個後續請求都將包含JWT,允許用戶訪問該令牌允許的路由,服務和資源。 單點登錄是當今廣泛使用JWT的一項功能,因為它的開銷很小,並且能夠輕鬆地跨不同域使用。
- Information Exchange(信息交換)
JSON Web Tokens是在各方之間安全傳輸信息的好方式。 因為JWT可以簽名:例如使用公鑰/私鑰對,所以可以確定發件人是他們自稱的人。 此外,由於使用標頭和有效載荷計算簽名,因此您還可以驗證內容是否未被篡改。
以上就是 JSON Web Token 相關知識,希望這篇文章對您的學習或者工作有所幫助,如果您覺得文章有幫助,歡迎幫忙轉發,謝謝。
最後
> 目前互聯網上很多大佬都有 JSON Web Token 相關文章,如有雷同,請多多包涵了。原創不易,碼字不易,還希望大家多多支持。若文中有所錯誤之處,還望提出,謝謝。
閱讀更多 平頭哥的技術博文 的文章