심심한잉여의 잡동사니

[Spring]필터(Filter) 와 인터셉터(Interceptor)차이 및 용도 본문

코딩일기/Spring&SpringBoot

[Spring]필터(Filter) 와 인터셉터(Interceptor)차이 및 용도

심심한잉여 2022. 3. 21. 21:25
반응형

필터(Filter)란?
디스패처 서블릿에 요청이 전달되기 전/후에 URI패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공하는 것
디스패처서블릿은 스프링의 가장 앞단에 존재하는 프론트 컨트롤러로서 필터는 스프링 범위 밖에서 처리가 되는 것
즉, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에서 관리 되는 것, 디스패처 서블릿 전/후에 처리하는 것

필터의 메소드
1. init 메소드
 - init메소드는 필터 객체를 초기화하고 서비스에 추가하기 위한 메소드, 웹 컨테이너가 1회 init 메소드를 호출하여 필터 객체를 초기화하면 이후의 요청들은 doFilter를 통해 처리된다.

2. doFilter 메소드
 - doFilter메소드는 URI패턴에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전에 웹 컨테이너에 의해 실행되는 메소드
doFilter의 파라메터로는 FilterChain이 있는데, FilterChain의 doFilter를 통해 다음 대상으로 요청을 전달하게 된다.

3. destroy 메소드
 - destroy 메소드는 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드이다.
이는 웹 컨테이너에 의해 1번 호출되며 이후에는 이제 doFilter가 처리되지 않는다.


인터셉터(Interceptor)란?
Spring이 제공하는 기술로써, 디스패처서블릿이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공한다. 즉, 웹 컨테이너에서 동작하는 필터와 달리 인터셉터는 스프링 컨텍스트에서 동작한다.

 

인터셉터의 메소드
1. preHandle 메소드
preHandle 메소드는 컨트롤러가 호출되기 전에 실행된다.
그렇기 때문에 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우에 사용할 수 있다.
preHandle의 3번째 파라메터인 handler 파라메터는 핸들러 매핑을 찾아준 컨트롤러 빈에 매핑되는 HandlerMethod라는 새로운 타입의 객체로써, @RequestMapping이 붙은 메소드의 정보를 추상화한 객체이다.
또한, preHandle의 반환 타입은 boolean인데 변환값이 true라면 다음 단계로 진행되지만 false라면 작업을 중단하여 이후의 작업은 진행되지 않는다.

2. postHandle 메소드
postHandle 메소드는 컨트롤러를 호출된 후에 실행한다. 
그렇기 때문에 컨트롤러 이후에 처리해야하는 후처리 작업이 있을 때 사용할 수 있다.
이 메소드에는 컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데, 최근에는 JSON 형태로 데이터를 제공하는 REST API 기반의 컨트롤러를 만들면서 자주사용되지는 않는다.

3. afterCompletion 메소드
afterCompletion 메소드는 이름 그대로 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행된다. 요청 처리 중에 사용한 리소스를 반환할 때 사용하기에 적합하다.

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 { } 
    
    }

 

인터셉터와 AOP
인터셉터 대신에 컨트롤러들에 적용할 부가 기능을 어드바이스로 만들어 AOP를 적용할 수 있다.
하지만 컨트롤러 호출 과정에 적용되는 부가기능들은 인터셉터를 사용하는 편이 낫다.
그 이유로는
1. Spring의 컨트롤러는 타입과 실행 메소드가 모두 제각각이라 포인트컷(적용할 메소드 선별)의 작성이 어렵다.
2. Spring의 컨트롤러는 파라미터나 리턴 값이 일정하지 않다.

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


필터(Filter) 와 인터셉터(Intercepter)의 차이

필터의 용도 및 예시
 1. 공통된 보안 및 인증/인가 관련 작업
 2. 모든 요청에 대한 로깅 또는 감사
 3. 이미지/데이터 압축 및 문자열 인코딩
 4. Spring과 분리되어야 하는 기능

필터에서는 기본적으로 스프링과 무관한하게 전역적으로 처리해야하는 작업들을 처리할 수 있다.
대표적인 예시로 보안과 관련된 공통 작업이 있으며 필터는 인터셉터보다 앞단에서 동작하기 때문에 전역적으로 해야하는 보안 검사를 하여 올바른 요청이 아닌 경우 차단이 가능하다.
그렇게되면 스프링 컨테이너까지 요청이 전달되지않고 차단되기 때문에 좀 더 안정성을 높일 수 있다.
또한 필터는 이미지나 데이터의 압축, 문자열 인코딩과 같이 웹 어플리케이션에 전반적으로 사용되는 기능을 구현하기 적당하다. Filter는 다음 체인으로 넘기는 ServletRequest/ServletResponse 객체를 조작할 수 있다는 점에서 Interceptor보다 훨씬 강력한 기술이라고 볼 수 있다. 

 

인터셉터의 용도 및 예시
 1. 세부적인 보안 및 인증/인가 공통 작업
 2. API호출에 대한 로깅 또는 감사
 3. Controller로 넘겨주는 정보의 가공

인터셉터에서는 클라이언트의 요청과 관련되어 전역적으로 처리해야 하는 작업들을 처리할 수 있다.
대표적으로 세부적으로 적용해야 하는 인증이나 인가와 같이 클라이언트 요청과 관련된 작업등이 있다. 예를 들어 특정 그룹의 사용자는 어떤 기능을 사용하지 못하는 경우가 있는데, 이러한 작업들은 컨트롤러로 넘어가기 전에 검사해야 하므로 인터셉터가 처리하기에 적합하다.
또한 인터셉터는 필터와 다르게 HttpServletRequest나 HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체를 조작할 수 는 없다. 대신 해당 객체가 내부적으로 갖는 값은 조작할 수 있으므로 컨트롤러로 넘겨주기위한 정보를 가공하기에 용이하다.
예를 들어 JWT 토큰 정보를 파싱해서 컨트롤러에게 사용자의 정보를 제공하도록 가공할 수 있는 것이다.
그 외에도 우리는 다양한 목적으로 API 호출에 대한 정보들을 기록해야할 수 있다.
이러한 경우에 HttpServletRequest나 HttpServletResponse를 제공해주는 인터셉터는 클라이언트의 IP나 요청 정보들을 포함해 기록하기에 용이하다.

대표적으로 필터를 인증과 인가에 사용하는 도구로는 SpringSecurity가 있다. SpringSecurity의 특징 중 하나는 SpringMVC에 종속적이지 않다는 것인데, 이러한 이유로는 필터 기반으로 인증/인가 처리를 하기 때문이다.

반응형