From 45d49bf8d943832051f43bd8df6b360d98751366 Mon Sep 17 00:00:00 2001 From: wjdwnsdnjs13 <67488973+wjdwnsdnjs13@users.noreply.github.com> Date: Sun, 21 Jul 2024 23:01:23 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=ED=97=A4=EB=8D=94=EC=9D=98=20jwt=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=EC=97=90=EC=84=9C=20memberId=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8A=94=20AOP=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/aop/JwtTokenAspect.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 application/src/main/java/org/depromeet/spot/application/common/aop/JwtTokenAspect.java diff --git a/application/src/main/java/org/depromeet/spot/application/common/aop/JwtTokenAspect.java b/application/src/main/java/org/depromeet/spot/application/common/aop/JwtTokenAspect.java new file mode 100644 index 00000000..38a9ee4a --- /dev/null +++ b/application/src/main/java/org/depromeet/spot/application/common/aop/JwtTokenAspect.java @@ -0,0 +1,59 @@ +package org.depromeet.spot.application.common.aop; + +import jakarta.servlet.http.HttpServletRequest; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.depromeet.spot.application.common.jwt.JwtTokenUtil; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Component +@Aspect +@RequiredArgsConstructor +@Slf4j +public class JwtTokenAspect { + + private final JwtTokenUtil jwtTokenUtil; + + private final HttpServletRequest request; + + // Before 사용 시 + // [ProjectingArgumentResolverRegistrar.class]: BeanPostProcessor before instantiation of bean + // failed + // 에러 발생함. 이유 아직 모르겠음 ㅠㅠ + // + // Q) Around는 ProceedingJoinPoint를 사용하여 메소드를 호출할 수 있고, + // 메서드의 인자를 변경하거나 직접적으로 메소드의 실행을 제어가능함. + // Before는 실행 전에만 동작하면서 메소드의 인자를 바꾸거나 직접 제어가 불가능함. + @Around("@annotation(org.depromeet.spot.application.common.annotation.MemberId)") + public Object getMemberIdFromTokenAspect(ProceedingJoinPoint joinPoint) throws Throwable { + String jwtToken = request.getHeader("Authorization"); + String access_token = jwtToken.split(" ")[1]; + log.info("jwtToken : {}", access_token); + log.info("memberId : {}", jwtTokenUtil.getIdFromJWT(access_token)); + Long memberId = Long.valueOf(jwtTokenUtil.getIdFromJWT(access_token)); + if (memberId != null) { + // 동작하는 메소드의 시그니처를 가져옴. + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Object[] args = joinPoint.getArgs(); + Class[] parameterTypes = signature.getParameterTypes(); + String[] parameterNames = signature.getParameterNames(); + + for (int i = 0; i < args.length; i++) { + if ("memberId".equals(parameterNames[i]) && parameterTypes[i] == Long.class) { + args[i] = memberId; // memberId로 변경 + } + } + + // 변경된 인자로 메서드 실행 + return joinPoint.proceed(args); + } + + throw new RuntimeException("토큰 내에 memberId가 없습니다."); + } +}