오늘은 어제 Filter에 이어 Interceptor에 대해 공부했다.
Dispatcher Servlet 전/후에 적용되어 요청과 응답을 참조하거나 가공하는 기능을 제공한다.
URL 패턴으로 대상을 구분해서 걸러낸다.
자바의 기능인 filter와 다르게 스프링 프레임워크의 기능이다.
스프링 Context 안에서 동작한다.
스프링 내의 모든 bean 객체에 접근이 가능하다.
org.springframework.web.servlet의 HandlerInterceptor인터페이스를 구현한다.
Filter와 다르게 HttpServletRequest나 HttpServletResponse 객체를 제공받기 때문에 객체 자체를 조작할 수는 없다. 대신 내부적의 값을 조작할 수 있기 때문에 정보를 가공하기에 용이하다.
preHandle()
컨트롤러가 호출되기 전 실행된다. boolean 반환타입으로, true면 다음 단계로 진행되고, false면 작업을 중단해 이후의 작업이 진행되지 않는다.
postHandle()
컨트롤러가 호출 된 후 view 페이지 렌더링 전에 실행된다. 컨트롤러 하위계층에서 작업 중 예외가 발생하면 호출되지 않는다.
afterCompletion()
view 렌더링까지 마치고 모든 작업이 완료된 후에 실행된다. 요청 중 사용한 리소스를 반환할 때 사용하기 적합하다. 컨트롤러 하위계층에서 작업 중 예외가 발생해도 무조건 호출된다.
로그인 한 유저만 컨트롤러에 접근하도록 인터셉터로 설정했다. preHandle를 써서 컨트롤러에 접근하기 전에 적용했다. (Spring Security로 구현하는게 더 적절하다고 생각하지만, 인터셉터를 구현해보기 위해 아래와 같은 방법을 써봤다.)
@Component
public class AuthInterceptor implements HandlerInterceptor {
// 로그인 하지 않은 유저는 login 페이지로 redirect.
// 로그인 한 유저만 접근 가능하게 설정
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (!isUserLogin()) {
response.sendRedirect("/login");
return false;
}
return true;
}
private boolean isUserLogin(){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
return true;
}
return false;
}
}
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {
private final AuthInterceptor authInterceptor;
// interceptor를 등록
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/post/**"); // 인터셉터 적용 경로를 지정
}
}