- ApiAccessLog 엔티티: 사용자/도메인/URI/파라미터/응답코드/처리시간 기록 - HandlerInterceptor로 /api/** 전체 요청 자동 기록 (health 제외) - Origin 헤더로 guide/wing 도메인 구분 - @Async 비동기 저장으로 응답 지연 방지 - GET /api/admin/audit-logs 관리자 조회 API (필터: origin, userId, uri, 기간) - ClientIpUtils 유틸 분리 (AuthController에서 공용화) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
72 lines
2.0 KiB
Java
72 lines
2.0 KiB
Java
package com.gcsc.guide.auth;
|
|
|
|
import io.jsonwebtoken.Claims;
|
|
import io.jsonwebtoken.JwtException;
|
|
import io.jsonwebtoken.Jwts;
|
|
import io.jsonwebtoken.security.Keys;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
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;
|
|
|
|
@Slf4j
|
|
@Component
|
|
public class JwtTokenProvider {
|
|
|
|
private final SecretKey secretKey;
|
|
private final long expirationMs;
|
|
|
|
public JwtTokenProvider(
|
|
@Value("${app.jwt.secret}") String secret,
|
|
@Value("${app.jwt.expiration-ms}") long expirationMs
|
|
) {
|
|
this.secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
|
|
this.expirationMs = expirationMs;
|
|
}
|
|
|
|
public String generateToken(Long userId, String email, boolean isAdmin) {
|
|
Date now = new Date();
|
|
Date expiry = new Date(now.getTime() + expirationMs);
|
|
|
|
return Jwts.builder()
|
|
.subject(userId.toString())
|
|
.claim("email", email)
|
|
.claim("isAdmin", isAdmin)
|
|
.issuedAt(now)
|
|
.expiration(expiry)
|
|
.signWith(secretKey)
|
|
.compact();
|
|
}
|
|
|
|
public Long getUserIdFromToken(String token) {
|
|
Claims claims = parseToken(token);
|
|
return Long.parseLong(claims.getSubject());
|
|
}
|
|
|
|
public String getEmailFromToken(String token) {
|
|
Claims claims = parseToken(token);
|
|
return claims.get("email", String.class);
|
|
}
|
|
|
|
public boolean validateToken(String token) {
|
|
try {
|
|
parseToken(token);
|
|
return true;
|
|
} catch (JwtException | IllegalArgumentException e) {
|
|
log.debug("JWT 토큰 검증 실패: {}", e.getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private Claims parseToken(String token) {
|
|
return Jwts.parser()
|
|
.verifyWith(secretKey)
|
|
.build()
|
|
.parseSignedClaims(token)
|
|
.getPayload();
|
|
}
|
|
}
|