본문 바로가기

Spring boot

[Spring Security] JWT사용할 때 filter, Interceptor 차이

 

왼쪽 사진 출처 :  https://justforchangesake.wordpress.com/2014/05/07/spring-mvc-request-life-cycle/

 

실행 순서: Filter → Interceptor → AOP → Interceptor → Filter

 

Filter와 Interceptor의 간단한 차이

출처 : https://mangkyu.tistory.com/173

 

Filter Interceptor
- Filter는 Dispatcher Servlet의 밖에 위치함.
    - Web Context에 존재하며 Spring context와 무관함.
- Interceptor는 Dispatcher Servlet 안에 위치함.
    - Spring context에 존재, 모든 Spring Bean에 접근 가능
- Request, Response 조작 가능
(여기서 조작이란 Request 와 Response 의 내부 상태를 변경한다는 것이 아닌 다른 객체로 바꿔친다는 의미)
- Request, Response 조작 불가능
- Application 실행 시, Filter chain을 순차적으로 실행 - request는 HandlerExecutionChain 속 알맞은 Handler를 거친 후, Controller로 이동한다. 
- filter를 추가하기 위해서는 javax.servlet의 Filter 인터페이스를 구현(implements)해야함. 이는 아래 method로 이루어져 있으니 필요한 method 오버라이드 하면 됨.

    - init(): 필터 인스턴스 초기화할 때의 로직
    - doFilter(): 실제 전/후 로직 처리
    - destroy(): 필터 인스턴스 종료할 때의 로직
- interceptor를 추가하기 위해서는 HandlerInterceptor 인터페이스나 HandlerInterceptorAdapter(Abstract Class)를 구현(implements)해야함. 이는 아래 method로 이루어져 있으니 필요한 method 오버라이드 하면 됨.

    - 각 method에서 true(계속 진행), false(중단)만 가능
    - preHandler(): 컨트롤러 메서드가 실행되기 전
    - postHanler(): 컨트롤러 메소드 실행 직후 view 페이지 렌더링 되기 전
    - afterCompletion(): view 페이지가 렌더링 되고 난 후
    - afterConcurrentHandlingStarted(): Servlet 3.0부터 비동기 요청이 가능해지며 생겨난 method로, 비동기 요청  PostHandle와 afterCompletion method를 대체
- 예외 발생 시, exception handler filter 만들기 - 예외 발생시, @ControllerAdvice에서 @ExceptionHandler 사용
- 사용 용도: 공통된 보안/인가 작업, XSS 방어, 인코딩 변환, 스프링과 분리된 작업 등등  - 사용 용도: 로그인 체크, 권한 체크(Login Session 검증, Header 검증, Token 검증 등등), 로그 확인

 

 

그래서 Filter와 Interceptor 중 JWT 검증에 뭘 사용할건데?

보통 로그인 체크, 권한 체크 등 (token, header 검증)은 Interceptor에서 이루어진다 한다. 

 

Interceptor의 로직을 살펴보니, 

1. token이 유효한지 -> token 속 memberId와 token값이 DB에서 가져온 값(memberId와 token)과 일치하는지

2. token이 유효한지 -> token 속 memberId가 DB에 있는지 -> Request 객체에 memberId 담기 (request.setAttribute())

또는

3. Interceptor에서 jwt 에서 내용을 추출해 bean(=POJO)을 하나 새로 만들어 값을 저장하고, controller 에서 이 bean 을 읽어서 jwt 에서 해석한 값을 꺼내와 사용

이었다.

 

 

결정사항

- token의 Stateless 특징을 살리려면 DB에 token 값이 저장돼서는 안 된다.

- Interceptor는 Controller에서 memberId를 꺼내려면 HttpServletRequest 객체에서 꺼내야한다. Controller는 DTO Request까지, request가 안그래도 많은데 memberId도 request 에서 꺼내야한다.(불편) 하지만 Filter는 memberId를 Authentication 객체에서 꺼낸다.(가독성 굿)

- Filter와 Interceptor의 구현 난이도 차이가 별로 없다. 

 

위 결정사항에 따르려면 Interceptor보다 Filter가 낫다고 생각했다. 

 

 

 

 

 

 

 

참고 :

interceptor이란? +  구현법: https://velog.io/@gillog/Spring-InterceptorHandlerInterceptor-HandlerInterceptorAdapter

filter, interceptor와 AOP 차이 : https://carnival.tistory.com/77, https://algopoolja.tistory.com/110

JWT에서 filter와 interceptor 차이 : https://okky.kr/questions/1213004