JWT(一):認(rèn)識 JSON WebToken
JWT(二):使用 Java 實現(xiàn) JWT
什么是 JWT?
JSON Web Token(JWT)是一種開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊且自包含的方式,作為 JSON 對象在各方之間安全的傳遞信息。這個信息可以通過數(shù)字簽名進(jìn)行驗證并信任。JWTs 可以使用密鑰(結(jié)合 HMAC 算法)或者 使用 RSA 、 ECDSA 加密的公鑰私鑰對進(jìn)行簽名。
盡管 JWTs 能夠在各方之間也提供安全加密,但是仍**專注于簽名 Token **。當(dāng)其他方隱藏了加密 Token 的某些聲明時,簽名 Token 可以驗證聲明的完整性。當(dāng)Token使用公鑰私鑰對進(jìn)行簽名時,這個簽名還能證明只有擁有私鑰的一方才是簽發(fā)它的一方。
什么時候使用 JWT ?
- 授權(quán):這是 JWT 最普遍的使用場景。當(dāng)用戶登錄之后,每次請求中都包含 JWT ,服務(wù)端允許用戶訪問那些只有攜帶 token 才能訪問的路由、服務(wù)、資源。目前在單點登錄中廣泛使用到 JWT ,因為它體積小,且能夠在不同域名之間使用。
- 信息交換: JWT 是一種能夠在各方之間安全傳輸信息的好方式。因為 JWTs 能夠簽名,比如使用公鑰私鑰對,你能夠確定發(fā)送者的身份。另外,簽名是使用 Header 和 Payload 通過特定算法計算而來,所以你也可以驗證內(nèi)容是否被篡改。
JWT的結(jié)構(gòu)
JWT 包含三部分,之間以點(.)連接
- Header(頭部)
- Payload(負(fù)載)
- Signature(簽名)
一個典型的 JWT 如同下面這樣:
xxxxx.yyyyy.zzzzz
一個真實的 JWT 例子:

Header
Header部分 是一個 JSON 對象,典型的header包含兩部分:
-
alg:使用的簽名算法,比如 HMAC SHA256 或 RSA -
typ:token的類型,比如 JWT
{
"alg": "HS256",
"typ": "JWT"
}
最后,用 Base64Url 將這個 JSON 對象編碼后,作為 JWT 的第一部分
Payload
Payload 部分也是 JSON 對象,用來存放數(shù)據(jù)。JWT 有7個官方字段:
- iss (issuer):簽發(fā)人
- exp (expiration time):過期時間,以秒為單位
- iat (Issued At):簽發(fā)時間,能夠算出JWT的存在時間
- nbf (Not Before):生效時間
- jti (JWT ID):JWT 的唯一標(biāo)識。用來防止 JWT 重復(fù)。
- sub (subject):主題(很少使用)
- aud (audience):token的受眾(很少被使用)
除了上面這些字段,還可以自定義私有字段,比如
{
"userId": "1101",
"userName": "張三",
"age": "23"
}
最后,用 Base64Url 將這個 JSON 對象編碼后,作為 JWT 的第二部分
Tip: JWT 默認(rèn)不加密,任何人都可以讀取,所以不要把敏感信息存放在這個部分,除非加密過。
Signature
使用 Header 指定的算法對 Header、Payload、密鑰三部分進(jìn)行簽名,生成的字符串作為 JWT 的第三部分。
比如使用 HMAC SHA256 算法進(jìn)行簽名:
HMACSHA256(
Base64Url.encode(header) + "." + Base64Url.encode(payload),
secret
)
簽名可以用來驗證數(shù)據(jù)是否被篡改,而且如果 token 使用私鑰進(jìn)行了簽名,那么該簽名還可以驗證 JWT 發(fā)送者的身份。
怎么使用 JWT ?
客戶端收到服務(wù)器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。
此后,客戶端每次請求服務(wù)器,都要帶上這個 JWT。所以可以把它放在 Cookie 里面自動發(fā)送,但是這樣并不能跨域,所以更好的做法是放在 HTTP 請求的頭信息 Authorization 字段里面。
Authorization: Bearer <token>
另一種做法是,跨域的時候,JWT 就放在 POST 請求的數(shù)據(jù)體里面。
JWT 的特點
- JWT 默認(rèn)是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次
- JWT 不加密的情況下,不能將敏感數(shù)據(jù)寫入 JWT
- JWT 不僅可以用于認(rèn)證,也可以用于交換信息
- JWT 的最大缺點是,由于服務(wù)器不保存 session 狀態(tài),因此無法在使用過程中廢止某個 token,或者更改 token 的權(quán)限。也就是說,一旦簽發(fā)了 JWT ,在到期之前就會始終有效
- JWT 本身包含了認(rèn)證信息,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用,JWT 的有效期應(yīng)該設(shè)置得比較短。對于一些比較重要的權(quán)限,使用時應(yīng)該再次對用戶進(jìn)行認(rèn)證。
- 為了減少盜用,JWT 不應(yīng)該使用 HTTP 協(xié)議明碼傳輸,要使用 HTTPS 協(xié)議傳輸。
和 Session-Cookie 相比
Session-Cookie 方式:客戶端每次請求都使用 cookie 攜帶 session_id ,服務(wù)器根據(jù) session_id 區(qū)分不同的會話
JWT 方式:客戶端每次請求都使用請求頭攜帶 token,服務(wù)器根據(jù) token 區(qū)分不同的用戶