[Spring] 스프링 인터셉터(Interceptor)

스프링 인터셉터(Interceptor)란?

interceptor는 위 처럼 가로챈다는 뜻을 갖습니다.

즉, 스프링 interceptor란 요청을 가로채서 개발자가 원하는 동작을 추가하는 역할을 합니다.

 

왜 interceptor를 사용해야하는 가?

스프링 interceptor는 웹과 관련된 공통 관심사를 해결하기 위한 기술로 대표적으로 공통 로그 처리, 권한 체크에 사용될 수 있습니다.

권한 체크를 예를 들면, 로그인을 해야 이용할 수 있는 페이지는 비로그인 사용자가 이용할 수 없어야 합니다.

interceptor를 이용해 요청을 받아 들이기 전, 세션에서 로그인한 사용자가 있는지 확인해보고 없다면 로그인 페이지로 redirect 시킬 수 있습니다.


스프링 인터셉터 구현하기 (HandlerInterceptor)

interceptor를 구현하기 위해서는 "HandlerInterceptor"를 Implements (구현)하면되고 HandlerInterceptor는 아래의 3가지 메서드를 제공합니다.

preHandler()
  • Controller가 호출되기 전에 실행
  • 컨트롤러가 실행 이전에 처리해야 할 작업이 있는경우 혹은 요청정보를 가공하거나 추가하는경우 사용합니다.
  • return 값은 boolean으로 해당 값이 false이면 컨트롤러 또는 다음 HandlerInterceptor를 실행하지 않습니다.

 

postHandler()
  • Controller가 호출 된 이후지만, View가 생성되기 전에 실행
  • ModelAndView 객체를 인자로 받아 Controller에서 View 정보를 전달하기 위해 작업한 Model 객체의 정보를 참조하거나 조작할 수 있습니다.
  • preHandle() 에서 리턴값이 fasle인경우 실행되지 않습니다.
  • 비동기적 요청처리 시에는 처리되지 않습니다.

 

afterCompletion()
  • View의 모든 작업이 완료된 후에 실행
  • preHandle() 에서 리턴값이 fasle인경우 실행되지 않습니다.
  • 비동기적 요청처리 시에는 처리되지 않습니다.

스프링 인터셉터 적용하기 (로그인 여부 체크)

 

로그인 체크 인터셉터 
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();

		// 기존 session이 있으면 기존 session을, 없으면 null 반환
        HttpSession session = request.getSession(false);

        if (session == null || session.getAttribute("loginMember") == null) {
            log.info("미인증 사용자 요청");
            // 로그인으로 redirect
            response.sendRedirect("/login?redirectURL=" + requestURI);
            return false;
        }
        return true;
    }
}

 

만약 세션이 비없거나,  "loginMember"를 키로 갖는 세션 객체가 없다면 로그인 페이지로 리다이렉트 하고, false를 반환 한 후, 그 다음 postHandler(), afterCompletion()로 넘어가지 않습니다.

 

인터셉터 등록
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginCheckInterceptor())
                .order(1)
                .addPathPatterns("/**") // 적용할 경로
                .excludePathPatterns("/", "/login", "/logout", "/css/**", "/*.ico", "/error"); // 제외할 경로
    }
}

 

WebMvcConfigurer를 구현해 addInterceptors() 메서드를 오버라이딩 하여 작성한 인터셉터를 registry에 추가합니다.

order() 인터셉터의 호출 순서를 지정한다. 낮을 수록 먼저 호출된다.
addPathPatterns() 인터셉터를 적용할 URL 패턴을 지정한다.
"/**" 는 모든 경로에 인터셉터를 적용한다는 뜻이다.
excludePathPatterns() 인터셉터에서 제외할 패턴을 지정한다.

위에서 등록한 인터셉터는 모든 경로에 로그인 체크 인터셉터를 적용 하되

"/", "/login", "/logout", "/css/**", "/*.ico", "/error" 경로는 로그인 인터셉터를 적용하지 않았습니다.