華為一面:談談你對JWT的理解?
JWT(JSON Web Token) 是一種開放標準(RFC 7519),用于在網絡應用間安全傳輸信息,通常用于身份驗證和信息交換。其核心特點是通過緊湊且自包含的 JSON 對象傳遞數據,無需服務端存儲會話狀態。
1.為什么需要JWT?
開發中需要 JWT 的主要原因是為了解決傳統基于 Session 的身份驗證方法中存在的問題,比如跨域認證不便、擴展性差等問題。而 JWT 允許我們設計無狀態的、分布式的 Web 應用,通過在每個請求中傳遞 Token 來驗證用戶身份,從而實現更加靈活和可擴展的架構。
2.執行流程
JWT 執行流程如下:
它的主要執行流程如下:
- 用戶登錄成功后,服務器根據用戶信息生成一個 JWT 的 Token 令牌。
- 服務器將此 Token 返回給客戶端,客戶端通常存儲在 Cookie 或 LocalStorage 中。
- 之后客戶端在訪問服務器端時會攜帶這個 Token,一般放在 HTTP 頭中。
- 服務器接收到請求后,解析 JWT,驗證其簽名有效性以及是否過期。
- 如果驗證成功,則處理相應的請求;否則,返回錯誤信息(重新登錄)。
3.JWT組成
JWT 是由三部分組成的:
- Header(頭部):通常由以下兩部分組成:
a.Token 類型:通常是 JWT。
b.加密算法:例如 HS256(HMAC SHA-256)、RS256(RSA SHA-256)等。
- Payload(載荷) :JWT 的主體部分,通常為以下三類:
- 標準聲明(Registered Claims):預定義的字段,如 iss(發行者)、exp (過期時間)、sub(主題)等。
- 公共聲明(Public Claims):用戶自定義的字段,例如用戶 ID、用戶名、角色等。
- 私有聲明(Private Claims):在特定場景下使用的字段,通常用于內部系統。
- Signature(簽名):用于驗證 Token 的完整性和防止篡改。
它們之間用點“.”分隔,形成一個字符串(Token)。
4.JWT核心實現代碼
在 Spring Boot 項目中,首先要引入 JWT 工具依賴,之后通過以下核心代碼可以生成 Token,以及驗證 Token:
// 生成 JWT(示例)|SECRET_KEY 為服務保存的密鑰。
public String generateToken(UserDetails user) {
return Jwts.builder()
.setSubject(user.getUsername())
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// 驗證 JWT(示例)
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
注意事項
- 密鑰安全:簽名密鑰需妥善保管,并定期修改,避免泄露。
- 無狀態性:JWT 無需服務端存儲會話信息,適合分布式系統。
5.JWT VS Session
JWT 和 Session 主要區別如下:
- 存儲位置不同:Session 通常將用戶會話信息存儲在服務器端,而 JWT 則將信息存儲在客戶端。
- 狀態管理不同:Session 是基于服務端的狀態機制,需要服務器保存會話狀態;JWT 是無狀態的,所有的信息都包含在 Token 中,服務端無需保存任何狀態。
- 隱私性不同:由于 JWT 的信息直接暴露給用戶,因此敏感信息不應該存儲在 JWT 中。Session 因為只在服務端維護,隱私性相對更好一些。
- 擴展性和性能不同:JWT 非常適合分布式系統,因為它不依賴于服務端的狀態。對于大型分布式系統,JWT 可以顯著減少服務器資源的消耗,提高系統的響應速度。
6.JWT存在的問題
盡管 JWT 有很多優點,但也存在一些挑戰:
- 大小限制:由于 JWT 是以 HTTP 頭部的形式發送的,所以它的大小受到限制。如果 JWT 中包含過多的數據,可能會導致請求頭過長的問題。解決辦法是盡量保持 JWT 簡潔,僅包含必要的信息。
- 令牌撤銷問題:一旦 JWT 被簽發,除非過期,否則無法輕易撤銷。
- 安全性考慮:雖然 JWT 本身支持簽名和加密,但如果密鑰泄露,將會導致嚴重的安全隱患。因此,確保密鑰的安全管理和定期更新是非常重要的。
小結
JWT 提供了一種有效的方法來處理用戶身份驗證和信息交換的問題,也是目前主流的用戶登錄驗證機制,但同時也需要注意上述提到的一些潛在風險和限制,它更適用于分布式大型項目的用戶信息傳輸和登錄權限判斷。