Spring Security로 JWT 기반 로그인을 구현중이다.
이 때, 요청이 들어오면 필터에서 토큰을 읽고, 인가하는 로직이 존재한다. 이는 다음과 같다.
@Component
@RequiredArgsConstructor
@Slf4j
public class JwtFilter extends OncePerRequestFilter {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String BEARER_PREFIX = "Bearer";
private final TokenProvider tokenProvider;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String token = getToken(request);
if (token != null && tokenProvider.validateToken(token)) {
Authentication authentication = tokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(request, response);
}
...(생략)
tokenProvider.getAuthentication(token);에서 DB에 접근하는 코드가 있다. 그러나 매 요청마다, 쿼리가 두 번씩 나갔다!
처음에는 해당 부분 로직 문제인줄 알았는데, 알고보니 Filter 자체가 두번 호출되는 것이였다.
응? OncePerReqeustFilter는 한번만 실행 보장 아닌가??
라고 하면 맞는말이긴 하다!
여기서 문제는, 내가 저 커스텀 필터를 Spring Security의 config에서 다음같이 등록해뒀다.
.addFilterBefore(new JwtFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
스프링에서는, @Bean으로 등록된 것중 필터가 있다면 자동으로 필터체인에 등록한다.
그런데, 내가 추가로 Config를 통해 필터체인의 특정 부분에 추가로 등록하였기 때문에 두 번 호출되는 것이다.
단순하다. 그냥 @Component를 제거해서 스프링 빈으로 등록하지 않으면 된다. 습관성 빈 등록을 주의하자!