package com.weiwojc.utils; import com.weiwojc.model.entity.User; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component @RequiredArgsConstructor public class JwtUtils { private static final long SERVER_START_TIME = System.currentTimeMillis(); @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; private final TokenBlacklistManager tokenBlacklistManager; private SecretKey getSigningKey() { byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8); return Keys.hmacShaKeyFor(keyBytes); } public String generateToken(User user) { Map claims = new HashMap<>(); claims.put("userId", user.getUserId()); claims.put("username", user.getUsername()); claims.put("instanceId", tokenBlacklistManager.getInstanceId()); claims.put("serverStartTime", SERVER_START_TIME); return Jwts.builder() .setClaims(claims) .setSubject(user.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) .signWith(getSigningKey()) .compact(); } public Claims getClaimsFromToken(String token) { return Jwts.parserBuilder() .setSigningKey(getSigningKey()) .build() .parseClaimsJws(token) .getBody(); } public String getUsernameFromToken(String token) { return getClaimsFromToken(token).getSubject(); } public Long getUserIdFromToken(String token) { return getClaimsFromToken(token).get("userId", Long.class); } public String getInstanceIdFromToken(String token) { return getClaimsFromToken(token).get("instanceId", String.class); } public Date getExpirationDateFromToken(String token) { return getClaimsFromToken(token).getExpiration(); } public boolean isTokenExpired(String token) { Date expiration = getExpirationDateFromToken(token); return expiration.before(new Date()); } public boolean validateToken(String token) { try { Claims claims = getClaimsFromToken(token); if (isTokenExpired(token)) { return false; } String tokenInstanceId = claims.get("instanceId", String.class); String currentInstanceId = tokenBlacklistManager.getInstanceId(); if (!currentInstanceId.equals(tokenInstanceId)) { return false; } Long tokenServerStartTime = claims.get("serverStartTime", Long.class); if (tokenServerStartTime == null || tokenServerStartTime != SERVER_START_TIME) { return false; } if (tokenBlacklistManager.isBlacklisted(token)) { return false; } return true; } catch (Exception e) { return false; } } }