토큰 검증 코드에서 발생한 무한루프 shouldNotFilter로 해결

김수호·2024년 10월 14일
log.info("로그인 재요청");

                        String userId = jwtTokenProvider.getUserIdFromToken(accessToken);
                        String provider = jwtTokenProvider.getProviderTypeCodeFromToken(accessToken);
                        
                        //로그아웃 처리
                        logoutService.logoutsocial(provider.toLowerCase(), userId);


                        OAuth2AuthorizedClient authorizedClient = authorizedClientService.loadAuthorizedClient("kakao", userId);


                        senior.setRefreshToken(null); // 리프레시 토큰 무효화
                        seniorRepository.save(senior);


                        response.addCookie(cookieUtil.removeCookie("Authorization"));
                        response.addCookie(cookieUtil.removeCookie("Refresh-Token"));


                        cookieUtil.removeCookie("Refresh-Token");

                        response.sendRedirect("/api/logout/result");

Q. JWT의 만료엑세스 토큰과 리프레쉬 토큰이 만료되었을 때 무한으로 리다이렉트하는 현상이 발생하였다.

일단 response.sendRedirect("/api/logout/result"); 이를 통해서 무한으로 루프가 일어나게 되었다.

OncePerRequestFilter extend 를 하게 되면 요청 1번당 1번이 실행되어 문제가 없을 것이라고 생각했다.

그러던 중 익명 사용자에 대한 문제일지도 모르겠다는 생각이 들게 되었다.

Q. authentication에 AnonymousAuthenticationToken에 대한 문제인가?

그 결과 authentication에는 null값이 들어가 있었다.
그렇다면 내가 실행한 필터의 위치는 anonymous를 선언해주기 전이라는 이야기다.

그럼 필터 순서에 대해서 한번 알아봐야 할 것 같았다.

확인해보니 내 생각이 맞았다.
어나니머스는 거의 맨 뒤에 존재하였고, 나의 jwt 검증 필터는 oauth2Login 필터 앞에 실행하게 되어있으므로 null이 나오는게 맞았다.

그렇다면 어떤 방법이 있는지 잘 모르겠어서 영상들을 보면서 스프링 시큐리티에 대해서 한참을 알아보았다.

Q. 팀원이 username으로 로그인하는 기능과 소셜로그인의 검증 필터를 나눠보자는 의견을 제시하게 된다.

팀원의 의견에 따라 불리하고 코드를 출력하게 되었다.
기존 통합되어 있던 코드에서 email 부분을 email filter로 이전하게 되었다.


.addFilterBefore(jwtEmailFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(jwtAuthenticationFilter, OAuth2LoginAuthenticationFilter.class)

위와 같이 커스텀 필터를 변경하게 되었다.

redirect의 대한 부분은 여전히 같은 문제가 발생하였다.

새로운 해결책? shouldNotFilter의 발견

이 필터는 특정 조건에 따라 필터를 건너뛸 수 있도록 제어를 하는 코드이다.
나는 /api/logout/result 이처럼 permit all 되어있는 코드에 대해서는 굳이 추가 검증을 할 필요가 없다고 생각했다.
그럼 이 필터를 통해서 jwt 검증에 대해서 우회한다면 문제가 없을것이라 생각하게 되었고
임시로 코드를 추가하게 된다.

  // 리다이렉트되는 특정 URL을 정의합니다 (예: "/api/logout/result")
   private static final String LOGOUT_RESULT_URL = "/api/logout/result";

   @Override
   protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
       System.out.println("shouldNotFilter (JwtEmailFilter)");
       // 특정 URL로 리다이렉트되는 경우 필터를 건너뛰도록 설정
       String path = request.getRequestURI();
       return LOGOUT_RESULT_URL.equals(path);
   }

이 코드를 추가 한 뒤로 무한 리다이렉트 문제는 해결이 되었다.
url을 정리해서 permit all에 대한 url 정리를 하여 한번에 처리가 이뤄질 수 있도록 하면 좋을 것 같다.

profile
정답을 모르지만 답을 찾는 법을 알고, 그 답을 찾아낼 것이다. 그럼 괜찮지 않은가? -크리스 가드너-

0개의 댓글