Jwts用于創建和驗證 ??JSON Web Token(JWT)?? 的開源庫詳解
在 Java 開發中,提到 Jwts
通常指的是 ??JJWT(Java JWT)庫??中的核心工具類 io.jsonwebtoken.Jwts
。JJWT 是一個專門用于創建和驗證 ??JSON Web Token(JWT)?? 的開源庫,而 Jwts
類是其提供的??入口工具類??,主要用于??構建(簽名)JWT?? 和??解析(驗證并提取內容)JWT??。
??Jwts 的核心作用??
Jwts
類的核心功能圍繞 JWT 的??生命周期??展開,主要包括兩大操作:
- ??構建并簽名 JWT??(生成 Token):將業務數據(聲明)打包為 JWT,并通過密鑰或私鑰進行簽名,確保 Token 不可篡改。
- ??解析并驗證 JWT??(解析 Token):驗證 JWT 的簽名有效性,并提取其中的聲明(如用戶信息、過期時間等)。
??一、構建并簽名 JWT(生成 Token)??
通過 Jwts.builder()
方法創建一個 JWT 構建器(JwtBuilder
),逐步設置 Token 的??聲明(Claims)??和??簽名參數??,最終生成簽名的 JWT 字符串。
??關鍵步驟與方法??
??設置基礎聲明(必選)??:
JWT 規范定義了一些標準聲明(Claims),Jwts
提供了便捷方法設置這些聲明:setIssuer(String iss)
:設置簽發者(Issuer)。setSubject(String sub)
:設置主題(Subject,通常是用戶標識)。setAudience(String aud)
:設置接收者(Audience)。setExpiration(Date exp)
:設置過期時間(必選,Token 失效時間)。setNotBefore(Date nbf)
:設置生效時間(可選,Token 在此時間前無效)。setIssuedAt(Date iat)
:設置簽發時間(默認當前時間,可選)。
??設置自定義聲明(可選)??:
通過claim(String name, Object value)
方法添加業務相關的自定義聲明(如用戶角色、權限等)。??設置簽名算法和密鑰??:
通過signWith(SignatureAlgorithm alg, Key key)
方法指定簽名算法(如 HMAC SHA256、RSA 等)和對應的密鑰(對稱或非對稱)。
??示例:生成 JWT??
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.util.Date;public class JwtGenerator {// 生成安全的密鑰(僅示例,實際需妥善保管)private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);public static String generateToken(String userId, String role) {return Jwts.builder().setSubject(userId) // 主題(用戶ID).claim("role", role) // 自定義聲明:用戶角色.setIssuedAt(new Date()) // 簽發時間(默認當前時間).setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 過期時間(1小時后).signWith(SECRET_KEY) // 使用 HMAC-SHA256 算法簽名,密鑰為 SECRET_KEY.compact(); // 生成緊湊的 JWT 字符串}public static void main(String[] args) {String token = generateToken("user123", "admin");System.out.println("生成的 JWT: " + token);// 輸出示例:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzE2NTYzMjAwLCJleHAiOjE3MTY1NjY4MDB9.xxx...}
}
??二、解析并驗證 JWT(提取內容)??
通過 Jwts.parserBuilder()
方法創建一個 JWT 解析器(JwtParserBuilder
),設置驗證參數(如密鑰、算法),然后調用 parseClaimsJws(String jwt)
方法解析并驗證 JWT。若驗證通過,返回包含聲明的 Claims
對象;若驗證失敗(如簽名錯誤、已過期),則拋出異常。
??關鍵步驟與方法??
??設置驗證密鑰和算法??:
通過setSigningKey(Key key)
方法設置簽名驗證的密鑰(需與生成 Token 時的密鑰一致)。
若 Token 使用非對稱算法(如 RSA),需設置公鑰(setVerificationKey
)。??可選配置(如忽略過期時間)??:
通過requireExpiration(false)
等方法調整驗證策略(一般不建議忽略過期時間)。??解析并驗證??:
調用parseClaimsJws(String jwt)
方法解析 Token,返回Jws<Claims>
對象,通過getBody()
獲取聲明(Claims
)。
??示例:解析 JWT??
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.security.Keys;
import java.security.Key;public class JwtParser {private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 與生成時的密鑰一致public static Claims parseToken(String token) {return Jwts.parserBuilder().setSigningKey(SECRET_KEY) // 設置驗證密鑰.build().parseClaimsJws(token) // 解析并驗證 JWT.getBody(); // 獲取聲明內容}public static void main(String[] args) {String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzE2NTYzMjAwLCJleHAiOjE3MTY1NjY4MDB9.xxx..."; // 假設是生成的合法 Tokentry {Claims claims = parseToken(token);System.out.println("用戶ID: " + claims.getSubject()); // 輸出:user123System.out.println("角色: " + claims.get("role")); // 輸出:adminSystem.out.println("過期時間: " + claims.getExpiration()); // 輸出:過期時間戳} catch (Exception e) {System.out.println("Token 解析失敗: " + e.getMessage()); // 簽名錯誤、過期等場景會拋異常}}
}
?
在 Java 的 JWT(JSON Web Token)處理庫 ??JJWT(Java JWT)?? 中,Jwts
是一個核心工具類,主要用于??構建(生成)JWT?? 和??解析(驗證/讀取)JWT??。它本身是一個工廠類,提供靜態方法返回 JwtBuilder
(構建器)或 JwtParser
(解析器)實例,實際功能由這些實例的方法實現。
三、核心方法分類
Jwts
的方法主要分為兩類:??構建 JWT?? 和 ??解析 JWT??。
1. 構建 JWT(生成令牌)
通過 Jwts.builder()
獲取 JwtBuilder
實例,用于設置 JWT 的聲明(Claims)和簽名,最終生成 JWT 字符串。
常用方法:
方法 | 說明 |
---|---|
Jwts.builder() | 工廠方法,返回一個 JwtBuilder 實例,用于開始構建 JWT。 |
JwtBuilder.setSubject(String subject) | 設置 JWT 的主題(sub 聲明),通常為用戶標識。 |
JwtBuilder.setIssuer(String issuer) | 設置 JWT 的頒發者(iss 聲明)。 |
JwtBuilder.setAudience(String audience) | 設置 JWT 的接收者(aud 聲明)。 |
JwtBuilder.setExpiration(Date expiration) | 設置 JWT 的過期時間(exp 聲明,UTC 時間)。 |
JwtBuilder.setNotBefore(Date notBefore) | 設置 JWT 的生效時間(nbf 聲明,UTC 時間)。 |
JwtBuilder.setId(String id) | 設置 JWT 的唯一標識(jti 聲明),通常用于防重放攻擊。 |
JwtBuilder.claim(String name, Object value) | 自定義聲明(如 email 、role 等非標準聲明)。 |
JwtBuilder.signWith(SignatureAlgorithm algorithm, Key key) | 指定簽名算法(如 HS256 、RS256 )和密鑰(對稱或非對稱),完成簽名。 |
2. 解析 JWT(驗證與讀取)
通過 Jwts.parser()
獲取 JwtParser
實例,用于驗證 JWT 的簽名并解析其聲明。
常用方法:
方法 | 說明 |
---|---|
Jwts.parser() | 工廠方法,返回一個 JwtParser 實例,用于開始解析 JWT。 |
JwtParser.setSigningKey(Key key) | 設置簽名驗證的密鑰(對稱或非對稱),必須與生成 JWT 時的密鑰一致。 |
JwtParser.requireIssuer(String issuer) | 強制驗證 JWT 的頒發者(iss 聲明)必須等于指定值(可選校驗)。 |
JwtParser.requireAudience(String audience) | 強制驗證 JWT 的接收者(aud 聲明)必須等于指定值(可選校驗)。 |
Jws<Claims> parseClaimsJws(String jwt) | 解析并驗證 JWT(帶 JWS 簽名),返回 Jws<Claims> 對象(包含頭部和聲明)。 |
Claims parseClaimsJwt(String jwt) | 解析 JWT(不驗證簽名,僅當已手動驗證過時使用,不安全!)。 |
四、示例代碼
生成 JWT(構建)
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.util.Date;// 生成密鑰(實際生產環境應安全存儲)
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);String jws = Jwts.builder().setSubject("user123") // 主題.setIssuer("my-app") // 頒發者.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 1小時后過期.claim("role", "admin") // 自定義聲明.signWith(key) // 簽名(使用 HS256 算法和密鑰).compact(); // 生成 JWT 字符串
解析 JWT(驗證與讀取)
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.security.Key;Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); // 必須與生成時的密鑰一致String jws = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIiwib3NfdXNlciI6Im15LWFwcCIsImV4cCI6MTY5MTYxNjAwMCwicm9sZSI6ImFkbWluIn0..."; // 實際 JWT// 解析并驗證簽名
var jwsClaims = Jwts.parser().setSigningKey(key).requireIssuer("my-app") // 強制驗證頒發者.parseClaimsJws(jws);// 讀取聲明
String subject = jwsClaims.getBody().getSubject(); // "user123"
String role = jwsClaims.getBody().get("role", String.class); // "admin"
Date expiration = jwsClaims.getBody().getExpiration(); // 過期時間
五、注意事項
- ??版本差異??:JJWT 0.11.x 及以上版本(支持 Java 8+)與舊版本(0.x 早期)API 略有不同(如
Key
類型從byte[]
改為java.security.Key
),需根據版本調整代碼。 - ??簽名驗證??:解析 JWT 時必須調用
signWith()
或setSigningKey()
驗證簽名,否則無法保證令牌未被篡改。 - ??聲明校驗??:推薦通過
requireIssuer()
、requireAudience()
等方法顯式校驗關鍵聲明,避免使用未驗證的令牌。 - ??密鑰安全??:對稱算法(如 HS256)的密鑰需嚴格保密;非對稱算法(如 RS256)需妥善管理公私鑰對。
?Jwts 支持的常見場景??
- ??單點登錄(SSO)??:用戶登錄后生成 JWT,后續請求攜帶 JWT 完成身份驗證。
- ??接口鑒權??:微服務間通過 JWT 傳遞用戶權限信息,避免重復查詢數據庫。
- ??無狀態認證??:服務端無需存儲 Token,通過簽名驗證即可確認 Token 合法性。
??注意事項??
- ??密鑰安全??:簽名密鑰(尤其是對稱算法的密鑰)需嚴格保密,泄露會導致 Token 被偽造。
- ??算法選擇??:推薦使用安全的算法(如 HS256、RS256),避免使用已廢棄的算法(如 HS384/HS512 需評估性能)。
- ??聲明的時效性??:必須設置
exp
(過期時間),防止 Token 長期有效被劫持。 - ??敏感信息避免明文??:JWT 內容僅 Base64 編碼(可解碼),不要存儲密碼等敏感信息。
??總結??
Jwts
是 JJWT 庫的核心工具類,主要用于??生成和解析 JWT??:
- ??生成 Token??:通過
Jwts.builder()
設置聲明和簽名,生成簽名的 JWT 字符串。 - ??解析 Token??:通過
Jwts.parserBuilder()
驗證簽名并提取聲明,確保 Token 合法性和數據完整性。
合理使用 Jwts
可以高效實現無狀態認證、跨服務鑒權等場景,是 Java 中處理 JWT 的首選工具。