로그인을 하지 않은 사용자는 게시판(경로: /boards
) 을 확인할 수 없게끔 컨트롤러를 구성했다고 해보자. 그러면 해당 컨트롤러의 메서드 마다 모두 로그인 여부를 확인하는 로직을 짜야한다. 즉, 수정이 발생하면 변경해야 되는 부분이 상당히 많아진다. 참고로 URL에 /boards
를 작성하면 막아지지 않고 들어가지는 문제도 발생한다. 이때 스프링 인터셉터를 활용하면 문제를 해결할 수 있다.
스프링 인터셉터는 웹의 공통사항을 처리해주는 기능이다. 공통사항의 예시로는 로그인 여부 확인 등이 있겠다. 인터셉터는 스프링 mvc 가 제공해주는 기능으로 적용 범위를 명확하게 이해할 필요가 있다. 먼저 적용 순서는 아래와 같다.
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
prehandle
posthandle
afterCompletion
이 3가지 기능을 중점적으로 살펴보면 된다.prehandle
은 컨트롤러가 호출하기 이전에 호출된다. 로그인되지 않은 사용자에게 게시판을 보여주지 않는다면 굳이 게시판과 관련된 컨트롤러를 호출시키지 않아도 된다. 따라서 이런 경우 prehandle
을 사용하면 된다.postHandle
은 컨트롤로 호출 후에 호출된다. 참고로 컨트롤러에서 예외가 발생한다면 postHandle
은 호출되지 않는다.afterCompletion
은 말 그대로 모든 과정이 완료된 후에 호출되는 메서드이다.(html이 랜더링된 후에 호출됨) afterCompletion
는 컨트롤러에서 예외가 발생해도 호출된다.HandlerInterceptor
를 상속받아서 preHandle
postHandle
afterCompletion
중 필요한 것을 오버라이드 하여 구현하면 된다.
아래는 세션으로 로그인을 확인하는 인터셉터 예제이다.
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
log.info("인증 체크 인터셉터 실행 {}", requestURI);
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("미인증 사용자 요청");
//로그인으로 redirect
response.sendRedirect("/members/login");
return false;
}
return true;
}
}
스프링 인터셉터의 구현이 완료되면 해당 인터셉터의 범위를 지정해주면 된다. 아래 코드를 참고하자.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginCheckInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns(
"/", "/members/login", "/members/logout", "/css/**",
"/*.ico", "/error", "/js/**"
);
}
}
WebMvcConfigurer
를 상속받아서 addInterceptors
를 오버라이드 하면 된다.
참고로 LoginCheckInterceptor
는 따로 구현한 스프링 인터셉터이다. addInterceptor 메서드에 추가해주면 된다.
order 는 여러개의 인터셉터가 있을때 우선순위를 결정한다.
addPathPatterns 는 해당 인터셉터가 적용하는 url 범위를 설정하면 된다.
excludePathPatterns 는 말 그대로 인터셉터를 적용하지 않을 경로를 뜻한다. 예로 들어 회원이 새롭게 로그인을 하거나 회원가입을 할때는 로그인 여부를 확인할 필요 없다. 따라서 excludePathPatterns 으로 로그인 혹은 회원가입 경로를 적용하면 된다.