当前位置: 当前位置:首页 > 娱乐 > jjwt工具类正文

jjwt工具类

作者:时尚 来源:焦点 浏览: 【大 中 小】 发布时间:2026-10-17 06:19:24 评论数:

第一次用JJWT的工具时候,我盯着Jwts.builder()那串链式调用看了半天——这玩意确实比手写Base64加HMAC清爽多了。工具JJWT(Java JWT)本质上就是工具个封装库,把JWT的工具创建、解析、工具验证这些脏活累活全包了。工具你不用再去手动拼接header、工具payload、工具signature,工具也不用担心Base64编码时漏掉padding导致服务端解析失败。工具

依赖引入很简单,工具Maven里加三行:

<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> 

注意jjwt-api是工具编译期依赖,另外两个runtime就够。工具这种拆分设计挺聪明——API模块只暴露接口,工具实现细节在运行时才加载,工具避免你的业务代码绑死某个JSON库。

生成Token的代码大概长这样:

Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); String jwt = Jwts.builder() .setSubject("user123") .claim("role", "admin") .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 3600_000)) .signWith(key) .compact(); 

这里有个坑我踩过:Keys.secretKeyFor()每次调用都会生成新密钥。你要是重启服务后还用旧Token,直接抛SignatureException。生产环境必须把密钥持久化,比如从配置文件读Base64字符串再Keys.hmacShaKeyFor()还原。

解析端更简单:

Jws<Claims> jws = Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token); String subject = jws.getBody().getSubject(); 

parseClaimsJws这名字有点绕,但记住一点:它会同时验证签名和过期时间。如果Token被篡改或者超时,直接抛异常,你不需要自己写if (exp < now)这种判断。

实际项目里我习惯包一层工具类,把密钥管理、异常处理、常用claim的读写都收进去。比如:

public class JwtUtil {  private final Key key; private final long ttlMillis; public JwtUtil(String secret, long ttlMillis) {  this.key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret)); this.ttlMillis = ttlMillis; } public String generate(String userId, Map<String, Object> claims) {  Date now = new Date(); return Jwts.builder() .setSubject(userId) .addClaims(claims) .setIssuedAt(now) .setExpiration(new Date(now.getTime() + ttlMillis)) .signWith(key) .compact(); } public Claims parse(String token) {  return Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token) .getBody(); } } 

这个类我用了两年多,基本没改过。addClaims比逐个claim()调用干净,parse方法把异常留给调用方处理——有人喜欢在里面catch然后返回null,我不推荐,因为空指针比异常更难排查。

HS256够用吗?看场景。单服务或者内部微服务之间,对称密钥没问题。要是Token要发给第三方验证,比如OAuth2场景,那就得换RS256,用私钥签、公钥验。JJWT对RS256的支持一样顺手,只是Keys.secretKeyFor换成KeyPairGenerator那套。

最后提一嘴版本。0.11.x和0.10.x的API差异不小,网上很多老教程还在用Jwts.parser().setSigningKey(),新版本已经改成parserBuilder()了。升级时注意signWith(SignatureAlgorithm, String)这种重载也被标记为废弃,推荐传Key对象。我去年帮人排查一个WeakKeyException,就是因为用了旧版API传字符串密钥,JJWT认为密钥强度不够直接拒绝。换成Keys.hmacShaKeyFor并保证密钥至少256位,问题消失。

工具类这东西,写一次省心很久。JJWT的文档不算特别友好,但源码结构清晰,遇到问题直接翻DefaultJwtParser和DefaultJwtBuilder,比搜StackOverflow快。