AOP와 JWT를 활용한 어드민 API 접근 로그 기록

이상민·2024년 9월 12일
0

오늘은 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을 만들었다. 이유는 클래스에 있는 특정 메서드에서만 이용하는 용도로 만들었는데, 내 생각에는 그럼 메서드에 어노테이션을 붙여서 사용하는 것이 더 효율적이라고 생각해서 이러한 방식으로 범위를 지정해주었다.

System.out.println 대신 log 사용하기

log를 이용해서 로그를 기록한 이유?

로그를 기록할 때는 System.out.println 대신 Slf4j를 사용해 로그 레벨을 관리하는 것이 좋다.

그 이유는 효율적으로 로그를 남기고 관리하기 위해서 이러한 방식으로 로그를 기록해보았다.

마무리

이렇게 AOP와 JWT를 활용해 어드민 API 접근 시 사용자 정보를 로그로 남기는 법을 정리해보았다. 앞으로 프로젝트에서 인증 및 로그 관리를 할 때 참고해서 추가 기능이 필요할 때,각 메서드에 직접 입력하여 추가하기 보다는 AOP기능을 활용해야 겠다.

profile
안녕하세요

0개의 댓글