Filter & Interceptor

Yeeun_Kim·2024년 6월 3일
0
post-thumbnail

1. Filter란?

  • 요청과 응답을 거른 뒤 정제하는 역할
  • Dispatcher Servlet에 요청이 전달되기 전/후에 URL패턴에 맞는 모든 요청에 대해 부가 작업을 처리할 수 있는 기능을 제공한다. 즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 되는 것이고, 스프링 범위 밖에서 처리되는 것이다.

1) Filter의 메소드

public interface Filter {

    default public void init(FilterConfig filterConfig) throws ServletException {}
	
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException;

    default public void destroy() {}
}
1-1) init()
  • Filter 객체를 초기화 하고 서비스에 추가하기 위한 메소드
  • 웹 컨테이너가 1회 init()을 호출하여 필터 객체를 초기화 하면 이후 요청들은 doFilter()를 통해 처리된다.
1-2) doFilter()
  • url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전 웹 컨테이너에 의해 실행되는 메소드
  • FilterChain 파리미터를 통해 다음 대상으로 요청을 전달 가능
  • chain.doFilter() 전/후에 우리가 필요한 처리 과정을 넣어 원하는 처리 진행 가능
1-3) destory()
  • Filter 객체를 제거하고 사용하는 사원을 반환하기 위한 메소드
  • 웹 컨테이너가 destroy()를 호출하여 필터 객체를 종료하면 이후에는 doFilter에 의해 처리되지 않음.

2. Interceptor란?

  • 요청에 대한 작업 전/후로 가로채는 곳
  • Dispatcher Servlet이 Controller를 호출하기 전/후에 Interceptor가 끼어들어 요청과 응답을 참조하거나 가공할 수 있는 기능 제공
  • 웹 컨테이너에서 동작하는 Filter와는 달리 Interceptor는 스프링 컨텍스트에서 동작한다.
  • Dispatcher Servlet이 핸들러 매핑을 통해 컨트롤러를 찾도록 요청하는데, 그결과로 실행 체인(HandlerExcutionChain)을 돌려준다. 여기서 1개 이상의 Interceptor가 등록되어 있다면 순차적으로 Interceptor들을 거쳐 컨트롤러가 실행되도록 하고, Interceptor가 없다면 바로 컨트롤러를 실행한다.

1) Interceptor의 메소드

public interface HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}
    
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}
    
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}
}
1-1) preHandle()
  • Controller가 호출되기 전 실행
  • Controller 이전에 처리해야하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우 사용
1-2) postHandle()
  • Controller가 호출된 후 실행(View 렌더링 전)
  • Controller 이후에 처리해야하는 후처리 작업이 있을 때 사용. 이 메소드는 컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데, 최근에는 JSON 형태로 데이터를 제공하는 RestAPI 기반의 컨트롤러(@RestController)를 만들면서 자주 사용되지 않음
1-3) afterCompletion()
  • 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행(View 렌더링 후)
  • 요청 처리 중에 사용한 리소스를 반환할 때 사용 가능

2) Interceptor / AOP

2-1) 컨트롤러는 타입과 실행 메소드가 모두 제각각이라 적용할 메소드 선별의 작성이 어렵다.
2-2) 컨트롤러는 파라미터나 리턴 값이 일정하지 않다.

인터셉터 대신에 컨트롤러들에 적용할 부가 기능을 어드바이스로 만들어 AOP를 적용할 수도 있다. 하지만 위와 같은 이유로 컨트롤러의 호출 과정에 적용되는 부가기능들을 인터셉터를 사용하는 편이 낫다.

즉, 타입이 일정하지 않고, 호출 패턴도 정해저있지 않기 때문에 컨트롤러에 AOP를 적용하려면 번거로운 부가 작업들이 생기게 된다.

3. Filter & Interceptor

1) Request, Response 객체 조작 가능 여부

  • Filter는 Request와 Response를 조작할 수 있다.
  • Interceptor는 Request와 Response를 조작할 수 없다.

2) 사용 사례

2-1) Filter 사용 사례
  • 보안 및 인증/인가 관련 작업
  • 모든 요청에 대한 로깅 또는 검사
  • 이미지/데이터 압축 및 문자열 인코딩
  • Spring과 분리되어야 하는 기능
  1. Filter는 기본적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 수 있다.
  2. Filter는 Interceptor보다 앞단에서 동작하기 때문에 보안 검사(XSS 방어 등)을 하여 올바른 요청이 아닌 경우 차단할 수 있다.
    -> 스프링 컨테이너까지 요청이 전달되지 못하고 차단되기 때문에 안전성을 높일 수 있다.
  3. Filter는 이미지나 데이터의 압축, 문자열 인코딩과 같이 웹 어플리케이션에 전반적으로 사용되는 기능을 구현하기에 적당하다.
2-2) Interceptor 사용 사례
  • 세부적인 보안 및 인증/인가 공통 작업
  • API 호출에 대한 로깅 또는 검사
  • Controller로 넘겨주는 정보(데이터)의 가공
  1. Interceptor에서 클라이언트의 요청과 관련되어 적역적으로 처리해야하는 작업들을 처리할 수 있다.
  2. 세부적으로 적용해야하는 인증이나 인가와 같이 특정 그룹의 사용자는 어떤 기능을 사용하지 못하는 경우에 해당 작업을 컨트롤러로 넘어가기 전에 검사해야 하므로 인터셉터가 처리하기에 적합하다.
  3. HttpServletRequest나 HttpServletResponse 등과 같은 제공받기 때문에 객체 자체를 조작할 수는 없다. 대신 해당 객체가 내주적으로 가지는 값은 조작할 수 있으므로 컨트롤러로 넘겨주기 위한 정보를 가공하기에 용이하다.
  4. 예시로 JWT 토큰 정보를 파싱해서 컨트롤러에게 사용자의 정보를 제공하도록 가공할 수 있다. 그 외에도 여러 목적으로 API 호출에 대한 정보를 기록해야하는 상황에 HttpServletRequest나 HttpServletResponse를 제공해주는 인터셉터는 클라이언트의 IP나 요청 정보들을 기록하기에 용이하다.

결론

  • Filter는 특정 요청과 컨트롤러에 관계없이 전역적으로 처리해야하는 작업이나 웹 어플리케이션에 전반적으로 사용되는 기능을 구현할 때 적용한다.
  • Interceptor는 클라이언트의 요청과 관련된 작업에 대해 추가적인 요구사항을 만족해야 할 때 적용한다.

참조

https://dev-coco.tistory.com/173

0개의 댓글