package com.TinyPro.utils;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtil {
private final Key secretKey;
@Value("${jwt.secret}")
private String secretString;
public JwtUtil(@Value("${jwt.secret}") String secretString) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = digest.digest(secretString.getBytes());
this.secretKey = new SecretKeySpec(keyBytes, SignatureAlgorithm.HS256.getJcaName());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to generate secret key", e);
}
}
* 生成 JWT
*
* @param email 用户的邮箱地址
* @param expiration JWT 的过期时间(毫秒)
* @return 生成的 JWT
*/
public String generateJwt(String email, long expiration) {
Map<String, Object> claims = new HashMap<>();
claims.put("email", email);
Date now = new Date();
return Jwts.builder()
.setClaims(claims)
.setSubject(email)
.setIssuedAt(now)
.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
.signWith(secretKey)
.compact();
}
* 解析 JWT
*
* @param jwt JWT 字符串
* @return 解析后的 JWT 声明
* @throws SignatureException 如果 JWT 签名无效
*/
public Claims parseJwt(String jwt) throws SignatureException {
try {
return Jwts.parserBuilder()
.setSigningKey(secretKey)
.setAllowedClockSkewSeconds(60)
.build()
.parseClaimsJws(jwt)
.getBody();
} catch (ExpiredJwtException e) {
throw new IllegalArgumentException("Token 已过期", e);
} catch (SignatureException e) {
throw new SignatureException("Invalid JWT signature");
} catch (Exception e) {
throw new IllegalArgumentException("Invalid JWT token", e);
}
}
* 传入旧 JWT,把过期时间整体 +2 分钟,返回新的 JWT
*
* @param oldJwt 原来的 token
* @return 延长 2 分钟后的新 token
*/
public String extendExpiration(String oldJwt) {
Claims claims = parseJwt(oldJwt);
Date newExp = new Date(System.currentTimeMillis() + 120_000);
return Jwts.builder()
.setClaims(claims)
.setSubject(claims.getSubject())
.setIssuedAt(new Date())
.setExpiration(newExp)
.signWith(secretKey)
.compact();
}
}