Search

응답이 세 번씩 왔던 이유

Tags
Spring Security
Date
2024/05/10

1. 개요

어떤 응답에 대해서 세 번씩 요청이 오는 경우가 생겼습니다. 이를 어떻게 해결했는지 간단하게 알아보고자 합니다.

2. doFilter()

@RequiredArgsConstructor public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenProvider jwtTokenProvider; private final UserRepository userRepository; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { /** * OAuth 토큰을 추출합니다. 구별을 위해 OAuth prefix를 사용합니다. */ String oAuthToken = jwtTokenProvider.extractOAuthToken(request) .orElse(null); /** * OAuth Token이 null이 아니라면 로그인 요청이니 다음 필터로 바로 넘어갑니다. */ if (oAuthToken != null) { // 1 filterChain.doFilter(request, response); } /** * 사용자 요청 헤더에서 RefreshToken을 추출합니다. * RefreshToken이 없거나 유효하지 않다면 null을 반환합니다. * 사용자 요청 헤더에 RefreshToken이 있는 경우는 AccessToken이 만료되었을 때입니다. * AccessToken이 만료되었다면 (403 ERROR) 후 클라이언트가 다시 요청합니다. */ String refreshToken = jwtTokenProvider.extractRefreshToken(request) .filter(jwtTokenProvider::isTokenValid) .orElse(null); if (refreshToken != null) { verifyRefreshTokenAndReIssueAccessToken(response, refreshToken); } if (refreshToken == null) { verifyAccessTokenAndSaveAuthentication(request, response, filterChain); } // 2 filterChain.doFilter(request, response); } private void verifyAccessTokenAndSaveAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { jwtTokenProvider.extractAccessToken(request) .filter(jwtTokenProvider::isTokenValid) .ifPresent(accessToken -> jwtTokenProvider.getSubject(accessToken) .ifPresent(email -> userRepository.findByEmail(email) .ifPresent(this::saveAuthentication))); // 3 doFilter(request,response); }
SQL
복사
최대한 많은 부분을 덜어놨는데요, 이 코드의 문제는 doFilter(request, response)가 많다는 것입니다. 사실 많은 것은 문제가 안됩니다. 중요한건 return; 즉, 메소드를 끝내지 않기 때문에 스택 처럼 doFilter(request, response)가 쌓여서 모두 다 실행된다는 점입니다.
이를 해결하려면 적절한 구간에 return; 코드를 삽입해서 메소드를 끝내주어야 합니다.
예를 들어. OAuth 로그인을 하는 과정임이 드러났다면
if (oAuthToken != null) { filterChain.doFilter(request, response); return; // return 문 삽입 }
Java
복사
다음과 같이 진행해주어야 합니다.