在日常的 Java Web 开发中,JWT(JSON Web Token)已经成为了实现无状态认证的标配。提到 Java 的 JWT 库,很多人第一时间会想到 jjwt。不可否认 jjwt 功能强大,但对于一些简单的项目或是微服务节点,繁琐的 Builder 和复杂的配置往往显得有些“杀鸡用牛刀”。
今天向大家分享一个基于 Auth0 提供的 java-jwt 库实现的超轻量级 JWT 工具类。它剔除了所有冗余配置,主打一个简单、直接、开箱即用,并且完全符合 JWT 标准规范。
1. 引入依赖
首先,我们需要在项目中引入 Auth0 的 java-jwt 依赖。相比于 jjwt 需要引入多个拆分的包,Auth0 只需要一个依赖即可搞定一切。
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>2. 核心工具类代码
下面是完整的 JwtUtils 实现。我们使用了 HMAC256 算法进行对称加密,包含了三个最核心的功能:生成 Token、校验 Token、解析负载。
package com.okcl.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.RegisteredClaims;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
/**
* JWT工具类
*/
public class JwtUtils {
// 定义固定的秘钥(实际开发中建议放入配置文件中读取,避免硬编码)
private static final Algorithm hmac256 = Algorithm.HMAC256("YLWTSMTJFYHDCMGSCWHSSYBZSDKC");
/**
* 生成token
*
* @param pub 负载(被认证的主体,如用户ID)
* @param expiresTime 过期时间(单位 毫秒)
* @return token
*/
public static String sign(String pub, Long expiresTime) {
return JWT.create()
// 生成令牌函数
// 使用 Subject 字段存储自定义负载,符合 JWT 标准规范
.withSubject(pub)
// 添加过期时间
.withExpiresAt(new Date(System.currentTimeMillis() + expiresTime))
.sign(hmac256);
}
/**
* 校验token
*/
public static boolean verify(String token) {
// 创建校验器,必须使用与签发时相同的算法和秘钥
JWTVerifier verifier = JWT.require(hmac256).build();
// 如果正确,直接代码向下执行;如果错误(过期、篡改),会抛出异常
verifier.verify(token);
return true;
}
/**
* 从token中获取负载
*
* @param token 令牌
* @return 保存的负载
*/
public static String getClaim(String token) {
// 直接解码 Token,不进行签名校验
DecodedJWT jwt = JWT.decode(token);
// 读取规范的 Subject 字段
Claim iss = jwt.getClaim(RegisteredClaims.SUBJECT);
return iss.asString();
}
}
3. 代码原理解析与细节优化
极简的加密方式:直接实例化
Algorithm.HMAC256(secret),复用同一个单例对象即可,减少了内存开销。规范的负载存储(重点优化):在
sign方法中,我们使用了.withSubject(pub)来存储业务数据(比如 UserID)。在 JWT 标准规范中,Subject (sub)字段正是用来标识 Token 所代表的“主体”。相比于滥用Issuer (iss)字段,使用sub不仅省去了自定义 Claim 的麻烦,更是让代码在语义上完全符合 RFC 7519 规范,读取时配合RegisteredClaims.SUBJECT常量,优雅且清晰。严格的异常控制:Auth0 的
verifier.verify(token)方法非常严谨。如果 Token 过期、签名不匹配或格式错误,它会自动抛出运行时异常。我们在 Spring Boot 的全局异常处理器(Global Exception Handler)中捕获相关异常即可统一处理鉴权失败的逻辑,让业务代码十分干净。
4. 测试与使用场景
使用这个工具类非常简单,以下是模拟业务场景的调用:
public class JwtTest {
public static void main(String[] args) {
String userId = "USER_8848";
// 1. 生成一个有效期为 1 小时的 Token (3600 * 1000 毫秒)
String token = JwtUtils.sign(userId, 3600000L);
System.out.println("生成的Token: " + token);
// 2. 校验 Token
try {
boolean isValid = JwtUtils.verify(token);
System.out.println("Token校验结果: " + isValid);
} catch (Exception e) {
System.out.println("Token已失效或被篡改!");
}
// 3. 提取业务数据
String extractedUserId = JwtUtils.getClaim(token);
System.out.println("解析出的用户主体(Subject): " + extractedUserId);
}
}
总结
并不是每一个项目都需要企业级、大而全的配置。对于很多中小型项目而言,Auth0 提供的这套 API 已经完美覆盖了鉴权的核心诉求。通过合理利用标准字段(如 Subject),我们既能保持代码的轻量,又能保证其规范性。如果你也厌倦了繁琐的 Token 配置代码,强烈推荐尝试这个极简方案!