오늘은 Spring AOP를 활용해 어드민 API에 접근할 때마다 로그를 남기고, JWT를 이용해서 요청한 사용자의 아이디가 로그로 나오도록 하는 과제를 수행했다.
언제, 어떤 사용자가 API에 접근했는지 기록하는 것이 필요했다. 이를 위해 Spring AOP의 @Before
어드바이스를 사용하여 특정 메서드에 접근하기 전, 로그를 기록할 수 있도록 설정했다.
참고 :
@Before
를 사용한 이유
@Around
는 메서드 실행 전후에 동작을 정의할 수 있어 더 유연한 처리가 가능합니다. 즉, 메서드 실행 전후에 공통적인 로직을 넣고, 메서드 실행 결과를 조작할 수도 있습니다.
@Before
는 단순히 메서드 실행 전에 로직을 실행하는 것에 집중하는 반면, @Around는 메서드 실행 전, 후 또는 메서드 실행 자체를 제어할 때 사용됩니다.
나는 단순히 로그 기록을 남기기 위해서 @Before
를 이용했다.
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.example.expert.config.JwtUtil;
import java.time.LocalDateTime;
@Aspect
@Slf4j
@RequiredArgsConstructor
public class SpringAspect {
private final HttpServletRequest request;
private final JwtUtil jwtUtil;
// @Pointcut("execution(* org.example.expert.domain.comment.controller.CommentAdminController.deleteComment(..))")
// private void deleteCommentLayer() {}
// @Pointcut("execution(* org.example.expert.domain.user.controller.UserAdminController.changeUserRole(..))")
// private void changeUserRoleLayer() {}
@Pointcut("@annotation(org.example.expert.domain.common.annotation.TrackTime)")
private void trackTimeAnnotation() {}
@Before("trackTimeAnnotation()")
public void logApiMethod() {
// 요청 헤더에서 Authorization 헤더의 JWT 토큰을 가져옴
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = jwtUtil.substringToken(authHeader);
Claims claims = jwtUtil.extractClaims(token);
String userId = claims.getSubject();
LocalDateTime localDateTime = LocalDateTime.now();
String requestUrl = request.getRequestURI();
log.info(userId+ " " + localDateTime+ " " + requestUrl);
}
}
}
나는 트랙타임이라는 커스텀 어노테이션을 따로 만들어서 @Pointcut
을 만들었다. 이유는 클래스에 있는 특정 메서드에서만 이용하는 용도로 만들었는데, 내 생각에는 그럼 메서드에 어노테이션을 붙여서 사용하는 것이 더 효율적이라고 생각해서 이러한 방식으로 범위를 지정해주었다.
log
를 이용해서 로그를 기록한 이유?
로그를 기록할 때는 System.out.println
대신 Slf4j
를 사용해 로그 레벨을 관리하는 것이 좋다.
그 이유는 효율적으로 로그를 남기고 관리하기 위해서 이러한 방식으로 로그를 기록해보았다.
이렇게 AOP와 JWT를 활용해 어드민 API 접근 시 사용자 정보를 로그로 남기는 법을 정리해보았다. 앞으로 프로젝트에서 인증 및 로그 관리를 할 때 참고해서 추가 기능이 필요할 때,각 메서드에 직접 입력하여 추가하기 보다는 AOP기능을 활용해야 겠다.