Files
dating/src/main/java/com/bao/dating/util/JwtUtil.java
2025-12-24 23:13:50 +08:00

205 lines
6.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.bao.dating.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* JWT工具类
* 提供JWT Token的生成、解析和验证功能
* @author KilLze
*/
public class JwtUtil {
/**
* 默认密钥(建议从配置文件读取)
*/
private static final String DEFAULT_SECRET = "dating-application-secret-key-for-jwt-token-generation-2025";
/**
* 默认过期时间(毫秒)- 7天
*/
private static final long DEFAULT_EXPIRATION = 7 * 24 * 60 * 60 * 1000L;
/**
* 生成JWT Token
* @param subject 主题通常是用户ID或用户名
* @return JWT Token字符串
*/
public static String generateToken(String subject) {
return generateToken(subject, DEFAULT_EXPIRATION);
}
/**
* 生成JWT Token自定义过期时间
* @param subject 主题通常是用户ID或用户名
* @param expiration 过期时间(毫秒)
* @return JWT Token字符串
*/
public static String generateToken(String subject, long expiration) {
return generateToken(subject, expiration, null);
}
/**
* 生成JWT Token带自定义claims
* @param subject 主题通常是用户ID或用户名
* @param expiration 过期时间(毫秒)
* @param claims 自定义claims
* @return JWT Token字符串
*/
public static String generateToken(String subject, long expiration, Map<String, Object> claims) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + expiration);
SecretKey key = getSecretKey();
if (claims == null) {
claims = new HashMap<>();
}
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
/**
* 生成JWT Token使用自定义密钥
* @param subject 主题
* @param expiration 过期时间(毫秒)
* @param secret 自定义密钥
* @return JWT Token字符串
*/
public static String generateTokenWithSecret(String subject, long expiration, String secret) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + expiration);
SecretKey key = getSecretKey(secret);
return Jwts.builder()
.setSubject(subject)
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
/**
* 从Token中获取Claims
* @param token JWT Token
* @return Claims对象
*/
public static Claims getClaimsFromToken(String token) {
return getClaimsFromToken(token, DEFAULT_SECRET);
}
/**
* 从Token中获取Claims使用自定义密钥
* @param token JWT Token
* @param secret 密钥
* @return Claims对象
*/
public static Claims getClaimsFromToken(String token, String secret) {
try {
SecretKey key = getSecretKey(secret);
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
throw new RuntimeException("解析JWT Token失败", e);
}
}
/**
* 从Token中获取主题通常是用户ID
* @param token JWT Token
* @return 主题字符串
*/
public static String getSubjectFromToken(String token) {
Claims claims = getClaimsFromToken(token);
return claims.getSubject();
}
/**
* 验证Token是否有效
* @param token JWT Token
* @return 是否有效
*/
public static boolean validateToken(String token) {
return validateToken(token, DEFAULT_SECRET);
}
/**
* 验证Token是否有效使用自定义密钥
* @param token JWT Token
* @param secret 密钥
* @return 是否有效
*/
public static boolean validateToken(String token, String secret) {
try {
Claims claims = getClaimsFromToken(token, secret);
return !isTokenExpired(claims);
} catch (Exception e) {
return false;
}
}
/**
* 检查Token是否过期
* @param claims Claims对象
* @return 是否过期
*/
private static boolean isTokenExpired(Claims claims) {
Date expiration = claims.getExpiration();
return expiration.before(new Date());
}
/**
* 获取Token的过期时间
* @param token JWT Token
* @return 过期时间
*/
public static Date getExpirationDateFromToken(String token) {
Claims claims = getClaimsFromToken(token);
return claims.getExpiration();
}
/**
* 获取默认密钥的SecretKey对象
* @return SecretKey对象
*/
private static SecretKey getSecretKey() {
return getSecretKey(DEFAULT_SECRET);
}
/**
* 根据字符串密钥生成SecretKey对象
* @param secret 密钥字符串
* @return SecretKey对象
*/
private static SecretKey getSecretKey(String secret) {
// 确保密钥长度至少为256位32字节以支持HS256算法
byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
if (keyBytes.length < 32) {
// 如果密钥太短,进行填充
byte[] paddedKey = new byte[32];
System.arraycopy(keyBytes, 0, paddedKey, 0, Math.min(keyBytes.length, 32));
return Keys.hmacShaKeyFor(paddedKey);
}
return Keys.hmacShaKeyFor(keyBytes);
}
}