jwt 工具类
时间: 2025-04-06 16:09:47 浏览: 67
### JWT 工具类实现示例
以下是基于 Java 的 JWT 工具类实现示例,该工具类支持创建和解析 JSON Web Token (JWT),并提供了签名验证功能以防止篡改[^2]。
```java
import io.jsonwebtoken.*;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
private static final String SECRET_KEY = "your_secret_key"; // 替换为实际使用的密钥
/**
* 创建 JWT
*
* @param claims 自定义载荷数据
* @param ttlMillis 过期时间(毫秒)
* @return JWT 字符串
*/
public static String createJwt(Map<String, Object> claims, long ttlMillis) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
return Jwts.builder()
.setClaims(claims) // 设置自定义载荷
.setIssuedAt(now) // 设置签发时间
.setExpiration(new Date(nowMillis + ttlMillis)) // 设置过期时间
.signWith(signatureAlgorithm, SECRET_KEY.getBytes()) // 使用 HMAC 签名算法和密钥进行签名
.compact();
}
/**
* 解析 JWT 并返回其中的 Claims 数据
*
* @param jwtToken 待解析的 JWT 字符串
* @return Claims 对象
* @throws ExpiredJwtException 如果令牌已过期则抛出异常
* @throws UnsupportedJwtException 如果不支持当前令牌类型则抛出异常
* @throws MalformedJwtException 如果令牌格式错误则抛出异常
* @throws SignatureException 如果签名验证失败则抛出异常
*/
public static Claims parseJwt(String jwtToken) throws JwtException {
return Jwts.parserBuilder()
.setSigningKey(SECRET_KEY.getBytes())
.build()
.parseClaimsJws(jwtToken)
.getBody();
}
}
```
上述代码实现了两个核心方法:
1. **`createJwt` 方法**:用于生成带有指定有效时间和自定义载荷的 JWT。通过 `SignatureAlgorithm.HS256` 和预设的密钥对生成的令牌进行签名,从而确保其不可被随意篡改。
2. **`parseJwt` 方法**:用于解析传入的 JWT,并提取其中的 Claims 数据。如果令牌已经过期、格式非法或者签名验证失败,则会分别抛出对应的异常[^3]。
---
### 防止 JWT 被篡改的关键机制
为了防止 JWT 被恶意修改或伪造,在生成 JWT 时会对整个头部和载荷部分计算哈希值,并将其作为签名附加到最终的字符串中。当接收方收到此令牌后,可以通过相同的密钥重新计算签名并与原始签名对比来验证其真实性。
例如,在上面的 `parseJwt` 方法中,调用了 `.setSigningKey(SECRET_KEY.getBytes())` 来设置解码所需的密钥。只有持有相同密钥的一方才能够成功完成校验过程;任何试图更改负载内容的行为都会破坏原有的签名结构,进而导致验证失败。
---
### 测试 JWT 的有效期
下面展示了一个简单的单元测试用例,演示如何利用前面提到的工具类检测某个特定时间段内的 token 是否仍然可用:
```java
@Test
public void testJwtValidityPeriod() throws Exception {
Map<String, Object> claims = Map.of("username", "testUser");
// 创建一个仅持续三秒钟的有效令牌
String shortLivedJwt = JwtUtils.createJwt(claims, 3_000L);
Thread.sleep(4_000); // 让线程休眠超过设定时限
try {
JwtUtils.parseJwt(shortLivedJwt);
fail("Expected an exception due to expired token.");
} catch (ExpiredJwtException e) {
System.out.println("Caught expected expiration error: " + e.getMessage());
}
}
```
在此例子中,我们故意让程序等待超出预期存活周期后再尝试解读刚才生产的短命凭证。不出所料的话,应该触发相应的超时期限警告消息。
---
####
阅读全文
相关推荐















