Introduction to JSON Web Tokens
好久沒有碼字了,今天來補個坑。本篇文章記錄一下JSON Web Tokens的概念以及如何使用。大部分內容直接翻譯自官方文件。
1、JSON Web Token是什麼
JSON Web Token (簡稱JWT)不是一項技術,而是為了讓JSON物件在各方之間安全地傳輸而制定的一項標準(RFC 7519)。這些資訊能夠被驗證和信任,因為他們是基於簽名演算法的,可以通過祕鑰驗證JWT的合法性以及資料是否被篡改。
常見的簽名演算法有HS256和RS256兩種,前一種稱為對稱演算法,他使用同一個祕鑰(secret)對簽名進行簽發和驗證。後一種稱為非對稱演算法,他提供一組公鑰和私鑰,採用公鑰進行簽發,採用私鑰進行驗證。(如果不能理解這個也沒啥事,看到後面自然就知道了。)
2、JSON Web Token 的組成
JWT的組成包括下面三個部分,每個部分之間用'.'隔開:
- Header
- Payload
- Signature
就是類似於"xxxxx.yyyyy.zzzzz"這個樣子的字串
2.1、Header
Header通常由兩個部分組成,token的型別以及使用的簽名演算法(例如HS256、RS256)
舉個栗子:
{
"alg": "HS256",
"typ": "JWT"
}
將頭部用Base64Url加密,構成了第一部分。
2.2、Payload
PayLoad是存放有效資訊的部分。它包括三個部分:
- Registered claims
- Public claims
- Private claims
Registered claims: 包括iss (簽發者), exp (過期時間), sub (主體), aud (接收者)等等,這是一組預定義的宣告,推薦但是不強制使用。
Public claims:由使用JWTs的使用者隨意定義。但是為了避免衝突,應該在IANA JSON Web令牌登錄檔中定義它們。
Private claims:由使用JWTs的使用者隨意定義。
舉個栗子
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
將PayLoad用Base64Url加密,構成第二部分
注意:由於Base64Url是可解密的,JWT僅保證他們不會被篡改,所以不應該在這些地方儲存敏感資訊。這個很重要!!
2.3、Signature
JWT的可靠性是由這個部分支援的,稱為簽名部分。我們一開始介紹的簽名演算法也是運用在這部分的。這部分由上述經過Base64Url加密後的Header和PayLoad以及一個祕鑰加密而成。如果說你使用HS256對稱演算法,如下
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
3、小結
經過上述的步驟最終生成的JWT形如下方字串的樣子。

- JWT的簽名部分保證了前兩部分是不會被篡改,一旦被惡意修改了,這個簽名在校驗時都會失敗
- JWT僅保證其內容不會被篡改,對於任意程式來說,前兩個包含資訊的部分都是可讀的,不應該將敏感資料存放在其中。
適用場景
作為傳統登入替換方案
JWT也是替換cookie-session的一種解決方案。相比於cookie-session的方案,他具有如下優點
1、伺服器不需要去維護session,節省記憶體開銷
2、支援移動端(安卓,ios)
3、支援跨域
1.客戶端請求認證伺服器進行登入認證2.認證伺服器執行校驗,校驗成功生成JWT並返回給客戶端(通常包含使用者名稱,過期時間等資訊)3.客戶端帶著JWT訪問服務A(通常是放在請求頭中),服務A校驗JWT(是否是合法的以及是否被篡改)。校驗通過則響應請求。