Spring) filter가 2번 실행되는 이유

오성민·2023년 2월 11일
0

spring

목록 보기
15/17

Spring Security를 이용한 로그인을 구현하는 중에 Access Token만 만료가 되었을 때 정상적으로 동작이 되지 않는 버그가 발생을 했다. 해당 내용을 해결하면서 배운 내용과 해결법을 정리하려고 한다.

시스템 구조

내가 구현한 서비스의 구조는

  • 최초 로그인을 진행했을 때 access token과 refresh token을 클라이언트에게 제공한다.
  • access token이 유효하지 않으면(아예 없거나 기간이 만료됨) refresh token과 함께 두 개를 재발급해줌(Refresh Token Rotation 방법)
  • refresh token과 userId를 DB에 저장해서 refresh token을 사용해서 요청을 보내면 해당 내용을 대조하여 해커의 공격에 대응함

이러한 구조를 가지고 인가를 진행함.

발생한 버그

refresh token을 이용해서 DB에 token value와 cookie에 있는 값을 비교하는 로직이 2번 반복되면서 실행이 됨.

버그가 발생한 결과

해당 버그가 발생하면서 비교가 2번 실행되면서 DB에 token value와 cookie에 refresh token value가 동일하지 않아 DB에 값이 계속해서 삭제되는 결과가 나옴.

처음 예상

로직 상에서 error가 발생하면서 어느 부분을 반복하는 것이라고 생각함.

해결법

의심되는 부분에 log를 사용해서 찍어보니 계속해서 2번이 찍히는 것을 확인
구글링에 검색어 'spring boot chain 2번 실행'이라는 키워드로 검색해보니 다행스럽게도 많은 자료가 있었다.

기존 filter class


public class JwtFilter extends GenericFilter

@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ------example------
    }

현재 filter class


public class JwtFilter extends OncePerRequestFilter

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    	------example------
    }

위와 같이 수정을 했다.

발생 원인

spring boot는 bean으로 등록된 것 중에서 filter가 있다면 자동으로 등록하고 실행시켜준다.
위와 같은 이유로 1번이 실행되고, 내가 spring security config class에서 addFilterBefore 메소드를 사용해서 한 번 더 등록을 하니 총 2번이 실행되었다.

하지만 oncePerRequestFilter Class는 한 번 실행되는 것이 보장된다고 한다.

그리고 해당 class를 사용하면 파라미터가 훨씬 사용하기 편한 형태이다.(기존에는 ServletRequest, Response -> HttpServletRequest, Response여서 cast가 필요하지 않음.)

내용을 이해하고 진행하는 것이 아닌 바로 적용하다보니 이해도가 너무 낮았던 것 같다.
문제가 발생하면 꼭 안되는 부분을 이해하고, 이걸 왜 사용하는지를 이해해야겠다. 그리고 log랑 debug를 잘 이용하자!

profile
풀스택을 지향하는 개발자

1개의 댓글

comment-user-thumbnail
2023년 6월 10일

감사합니다!

답글 달기