FireDrago
[Spring] 서블릿 필터와 스프링 인터셉터 본문

여러 메서드에서 로그인한 사용자만 접근할 수 있도록 하려면 어떻게 할까? 이렇게 여러 메서드에서 공통적으로 사용되는 기능을 '공통의 관심사'라고 한다. 공통의 관심사를 처리하기 위한 방법으로 AOP와 서블릿필터, 스프링 인터셉터가 있다.
이번 포스팅에서는 웹 요청 관련된 공통의 관심사를 처리하는 서블릿 필터와 스프링 인터셉터를 알아보자
1. 서블릿 필터

위 그림은 서블릿 필터가 작동하는 방식과 등록과정을 대략적인 그림으로 표현한 것이다.
우선 HTTP 요청이 오면 WAS 는 필터체인의 필터를 순서대로 실행한다.
필터가 수행된 뒤에 서블릿으로 요청이 전달된다.
필터는 Filter 인터페이스를 상속받아 정의한다. Filter 인터페이스에는 3가지 메서드가 있다.
init() 은 필터가 생성되어 등록될때 작동한다. doFilter() 는 필터가 실행될때 호출되는
필터의 로직을 정의한다. 마지막 destroy( )는 필터가 종료될때 실행된다.
destroy( )는 역순으로 실행된다. ( 위 그림에서는 3 -> 2 -> 1 순서)
필터를 등록할때는 @Configuration 애너테이션을 사용한 클래스에서 FilterRegistrationBean 객체를 사용한다
먼저 setFilter( ) 로 사용자가 정의한 필터를 생성하고, setOrder()와 addURLPatter() 을 사용하여
필터순서와 어떤 URL 요청이 왔을때 필터를 실행할지 설정해준다.
이제 서블릿 필터를 이용하여 로그인 인증을 확인하는 코드를통해 확인해보자

먼저 로그인 인증을 위한 필터를 정의한다. doFilter( ) 메서드만 정의해도 작동한다. (init, destroy는 default)
필터를 사용할때는 request, response를 HttpServletRequest 와 HttpServletResponse 로 다운캐스팅 한다.
그리고 화이트 리스트를 작성하여, 필터가 작동하지 않는 URI를 정의한다.
isLoginCheckPattern 에서 whiteList에 없는 URI인지 판단한다.
session이 없거나, 일치하는 session 아이디가 없다면, sendRedirect 호출하고,
반드시 return; 사용한다. 이후의 필터와 서블릿을 실행하지 않는다.
sendRedirect에서 호출한 주소를 파라미터로 전달하는데, 이는 로그인 이후 원래 요청페이지로 들어가도록 해준다.
필터로직이 끝나면 chain.doFilter(request, response) 를 통해 다음 필터를 실행할수 있도록 반드시 호출해야한다.

위에서 만든 로그인 인증 필터는 @Configuration 애너테이션을 사용한 클래스에서
@Bean 으로 등록한다. 이때 FilterRegistrationBean 객체가 사용된다. setFilter( ), setOrder( ), addURL( )
메서드를 사용하여 적용할 필터, 순서, URL 을 설정해준다.

컨트롤러의 로그인 메서드에서는 리다이렉트된 요청에 쿼리스트링으로 전달된 원래 요청을
@RequestParam 으로 받아온다. 이후 로그인이 완료되면 원래 요청으로 리다이렉트 시켜줄 수 있다.
2. 스프링 인터셉터
스프링 인터셉터 역시 공통의 관심사를 처리하는 기술이다. 스프링 MVC가 제공한다.
서블릿 필터와는 적용 순서와 범위, 사용방법이 다르다. 필터는 서블릿 이전에 실행되는 반면,
스프링 인터셉터는 DispatcherServlet 실행 이후에 요청된다.


스프링 인터셉터는 메서드에 따라 실행시점이 다르다. preHandler 메서드는 핸들러 요청 전에 실행된다.
postHandelr는 핸들러 요청이후 ModelAndView를 전달받은 다음, ModelAndView를 가지고 실행된다.
afterCompletion은 View가 렌더링 된 이후에 실행된다.
핸들러에서 예외가 발생한 경우 postHandler 는 실행되지 않지만, afterCompletion은 항상 실행된다.
심지어 예외정보를 가지고 출력 할 수도 있다. preHandler도 언제나 실행된다.
이제 로그인 인증을 스프링 인터셉터를 사용하여 처리해보자

HandlerInterCeptor 를 구현한다. preHandle 메서드에 인자인 Object handler는 매핑에따라 다른 핸들러 정보를
전달하므로 매핑 방식에 따라 확인해주어야 한다. 로그인 인증에서는 사용되지 않으므로 생략했다.


WebMvcConfigurer 인터페이스의 addInterceptors 메서드를 구현한다. 이때 인자로 전달된
InterceptorRegistry 의 addInterCeptor().order( ).addPathPatterns( ).excludePathPatterns( )를 이용하여 등록한다.
필터보다 더 정밀하게 URL 패턴을 지정 할 수 있다.
'프로그래밍 > Spring' 카테고리의 다른 글
| [Spring] 스프링 API 예외처리 (0) | 2024.02.20 |
|---|---|
| [Spring] 스프링 예외처리와 오류페이지 (0) | 2024.02.17 |
| [Spring] 로그인 쿠키와 세션 (0) | 2024.02.14 |
| [Spring] Bean Validation (0) | 2024.02.12 |
| [Spring] 검증처리 (0) | 2024.02.09 |
