在談及jwt原理前,我們其實對jwt并不陌生,對于有經驗的碼農,大都聽過或者實踐過,對于一些初學者,凡是談及安全方面的問題,總是覺得很復雜,感覺不是自己能搞得懂得,但其實無非也是加密解密的過程,不要想的太復雜,我們先說一說JWT在生產上的應用
JWT在生產上的應用
-
傳遞用戶身份信息: JWT 通常用于在前端和后端之間傳遞用戶身份信息。前端登錄成功后,服務端生成 JWT 令牌并返回給前端。前端隨后將令牌包含在每個請求的頭部,以便服務端驗證用戶身份。
-
無狀態身份驗證: JWT 的一大優勢是它是無狀態的,服務端不需要存儲用戶的登錄狀態。每個請求都包含了足夠的信息,使得服務端能夠驗證用戶身份而無需查詢數據庫。
-
單點登錄(SSO): JWT 也被廣泛用于實現單點登錄。用戶只需在一個認證中心登錄一次,然后通過 JWT 令牌在多個服務之間共享身份信息,而無需重復登錄。
-
過期處理: JWT 中通常包含一個過期時間(
exp
),服務端在驗證令牌時會檢查這個過期時間,確保令牌仍然有效。過期時間過后,令牌將不再被接受,這有助于提高安全性。
=========================================================================
前面我提到了,所謂生成令牌,驗證解析,無非就是有一套自己的加密,解密,驗證邏輯
生成JWT
在生成 JWT 令牌時,我們首先選擇一個密鑰(secretKey
),這個密鑰只有服務端知道。然后,我們定義一個包含用戶身份信息和其他聲明的 payload
。最后,我們使用選定的簽名算法(例如 HS256)對 payload
進行簽名,生成最終的 JWT 令牌。
public class JwtGenerator {public static String generateToken() {// 設置密鑰String secretKey = "your_secret_key";// 定義要包含在令牌中的聲明String token = Jwts.builder().setSubject("john_doe").claim("user_id", 123).setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 令牌有效期為一天.signWith(SignatureAlgorithm.HS256, secretKey).compact();return token;}public static void main(String[] args) {String token = generateToken();System.out.println(token);}
}
?原理
-
密鑰選擇: 選擇一個安全的隨機密鑰,確保只有授權的服務端知道這個密鑰。
-
Payload: Payload 是一個 JSON 對象,包含了我們想要傳遞的信息,例如用戶身份信息、權限等。它是令牌的主體部分。
-
簽名: 使用密鑰對 Payload 進行簽名,生成簽名部分。簽名的目的是確保令牌在傳輸過程中沒有被篡改。
驗證和解析 JWT 令牌?
?在接收到 JWT 令牌后,服務端需要驗證令牌的有效性,并解析其中的信息。
public class JwtValidator {public static void validateToken(String token) {// 設置密鑰String secretKey = "your_secret_key";try {// 驗證令牌并解碼 payloadClaims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();// 在此處可以檢查令牌中的聲明,例如過期時間// 如果過期時間在當前時間之前,則說明令牌已過期System.out.println("Token is valid. Claims: " + claims);} catch (SignatureException e) {System.out.println("Invalid token signature.");}}public static void main(String[] args) {String receivedToken = "your_received_token";validateToken(receivedToken);}
}
原理
-
解析器創建: 使用相同的密鑰創建一個 JWT 解析器。這個解析器將用于驗證和解析令牌。
-
驗證簽名: 解析器通過比對令牌中的簽名和使用密鑰重新計算的簽名來驗證令牌的完整性。如果簽名不匹配,說明令牌可能被篡改。
-
解碼 Payload: 如果簽名驗證通過,解析器會解碼令牌中的 Payload 部分。這樣,服務端就能獲取令牌中包含的用戶身份信息和其他聲明。
在生產中的應用:
-
傳遞用戶身份信息: JWT 通常用于在前端和后端之間傳遞用戶身份信息。前端登錄成功后,服務端生成 JWT 令牌并返回給前端。前端隨后將令牌包含在每個請求的頭部,以便服務端驗證用戶身份。
-
無狀態身份驗證: JWT 的一大優勢是它是無狀態的,服務端不需要存儲用戶的登錄狀態。每個請求都包含了足夠的信息,使得服務端能夠驗證用戶身份而無需查詢數據庫。
-
單點登錄(SSO): JWT 也被廣泛用于實現單點登錄。用戶只需在一個認證中心登錄一次,然后通過 JWT 令牌在多個服務之間共享身份信息,而無需重復登錄。
-
過期處理: JWT 中通常包含一個過期時間(
exp
),服務端在驗證令牌時會檢查這個過期時間,確保令牌仍然有效。過期時間過后,令牌將不再被接受,這有助于提高安全性。
注意事項
對于敏感操作,仍然需要考慮使用 HTTPS 來保護令牌在傳輸過程中的安全性。此外,令牌中不應包含敏感信息,因為它可以被前端解碼。敏感信息應該僅存儲在安全的后端。