增加jwtservice

This commit is contained in:
2025-05-08 15:53:09 +09:00
parent f6ee15f4f9
commit 779d94ba1b

View File

@ -0,0 +1,102 @@
package co.jp.app.service;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service
public class JwtService {
private static final Logger logger = LoggerFactory.getLogger(JwtService.class);
//log
@Value("${jwt.secret}")
private String secretKey;
@Value("${jwt.token-expiration-ms}")
private long tokenExpirationMs;
private Key getSignKey() {
byte[] keyBytes = Base64.getDecoder().decode(secretKey);
return Keys.hmacShaKeyFor(keyBytes);
}
public String extractUsername(String token) {
try {
return extractClaim(token, Claims::getSubject);
} catch (ExpiredJwtException e) {
logger.warn("JWT token is expired when extracting username: {}", e.getMessage());
return e.getClaims().getSubject();
} catch (MalformedJwtException | SignatureException | UnsupportedJwtException | IllegalArgumentException e) {
logger.error("Invalid JWT token when extracting username: {}", e.getMessage());
return null;
}
}
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
private Claims extractAllClaims(String token) {
return Jwts
.parserBuilder()
.setSigningKey(getSignKey())
.build()
.parseClaimsJws(token)
.getBody();
}
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, userDetails.getUsername());
}
private String createToken(Map<String, Object> claims, String subject) {
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + tokenExpirationMs)) // 使用配置的过期时间
.signWith(getSignKey(), SignatureAlgorithm.HS256)
.compact();
}
public boolean isTokenValid(String token, UserDetails userDetails) {
try {
final String username = extractUsername(token);
if (username == null) {
return false;
}
return (username.equals(userDetails.getUsername()) && !isTokenActuallyExpired(token));
} catch (ExpiredJwtException e) {
logger.warn("Token validation failed: Expired JWT - {}", e.getMessage());
return false;
} catch (MalformedJwtException | SignatureException | UnsupportedJwtException | IllegalArgumentException e) {
// 这些是更严重的token结构或签名问题
logger.error("Token validation failed: Invalid JWT (format, signature, etc.) - {}", e.getMessage());
return false;
}
}
private boolean isTokenActuallyExpired(String token) {
return extractExpiration(token).before(new Date());
}
private Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}
}