Mingyum-Kim / Iamhere

😉 국내 거주 외국인 매칭 서비스 "I-am-here" 😉
1 stars 0 forks source link

[Feature/#23] 게시글 생성 시 현재 사용자 정보 저장 #30

Closed Mingyum-Kim closed 1 year ago

Mingyum-Kim commented 1 year ago

23 : 해당 PR에 대한 이슈

29 : 로그인 된 사용자 정보 추출에 대한 이슈

To-do

Mingyum-Kim commented 1 year ago

PostService에서 아래와 같은 코드를 작성해 JWT 토큰을 얻어 MemberControllergetCurrentMember 메소드를 호출하였다. 그러나 토큰이 인증을 거치지 않는지 403 에러가 떴다.

 public Posts save(PostRequestDto dto) {
        Long memberId = memberApiClient.getCurrentMember();
        log.info("memberId : " + memberId);
        return postRepository.save(dto.toEntity(memberId));
    }

에러 전문


2023-07-11T10:36:01.128+09:00 ERROR 42392 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: feign.FeignException$Forbidden: [403] during [GET] to [http://MSA-IAMHERE-MEMBER/get-current-member] [MemberApiClient#getCurrentMember()]: []] with root cause

feign.FeignException$Forbidden: [403] during [GET] to [http://MSA-IAMHERE-MEMBER/get-current-member] [MemberApiClient#getCurrentMember()]: [] at feign.FeignException.clientErrorStatus(FeignException.java:226) ~[feign-core-12.1.jar:na] at feign.FeignException.errorStatus(FeignException.java:203) ~[feign-core-12.1.jar:na] at feign.FeignException.errorStatus(FeignException.java:194) ~[feign-core-12.1.jar:na] at feign.FeignException.errorStatus(FeignException.java:171) ~[feign-core-12.1.jar:na] at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:92) ~[feign-core-12.1.jar:na] at feign.ResponseHandler.decodeError(ResponseHandler.java:136) ~[feign-core-12.1.jar:na] at feign.ResponseHandler.handleResponse(ResponseHandler.java:70) ~[feign-core-12.1.jar:na] at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:116) ~[feign-core-12.1.jar:na] at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:72) ~[feign-core-12.1.jar:na] at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:98) ~[feign-core-12.1.jar:na] at jdk.proxy2/jdk.proxy2.$Proxy133.getCurrentMember(Unknown Source) ~[na:na] at com.personal.post.service.PostService.save(PostService.java:24) ~[main/:na] at com.personal.post.controller.PostController.save(PostController.java:24) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.6.jar:6.0.6] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.6.jar:6.0.6] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.6.jar:6.0.6] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.0.6.jar:6.0.6] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:547) ~[jakarta.servlet-api-6.0.0.jar:6.0.0] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.6.jar:6.0.6] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]



해결 방법은 아니지만, Feign Server에서 처리가 실패되어 에러가 발생한 경우 클라이언트 단에서 에러 원인을 확인하기 위해 Exception device를 이용해 에러 타입에 맞는 failur response entity를 반환하도록 수정하자. 
참고 자료 : https://velog.io/@_koiil/FeignClient-%EC%97%90%EB%9F%AC-%EB%A6%AC%EC%8A%A4%ED%8F%B0%EC%8A%A4-%EB%B2%84%EB%B8%94%EB%A7%81

또한, MSA 환경에서 Jwt 토큰을 이용해 인증하는 방식에 대해 검색해보면 **Api gateway**를 사용하는 경우가 많다. 왜 API gateway를 사용할까 ?

MSA에서 인증, 보안, 로깅의 역할인 API gateway는 클라이언트가 API gateway로 요청을 보내면 해당 요청의 JWT 토큰을 검증하는 작업을 수행한다. 따라서 사용자가 직접 토큰을 주입하지 않아도 API gateway가 알아서 토큰을 생성, 발급 후 Resource Server를 호출할 때 JWT 인증을 수행해주는 특징이 있다. 
참고 자료 : https://devs0n.tistory.com/27

그러나 Post 모듈에서 Member 모듈로 통신할 때 Member 모듈에서 발급된 JWT 를 사용하여 Feign 통신을 하였음에도 403 에러가 떴었다. 헤더에 Authorization이 NULL이 되는 문제 때문이었는데, 어째서 Header가 담긴 채로 통신이 되지 않는지는 여전히 의문이다. 

해당 PR은 우선 머지하고 API gateway를 설정 후 To-do를 추가 개발한다.