231017 TIL #218 Interceptor

김춘복·2023년 10월 17일
0

TIL : Today I Learned

목록 보기
218/571

Today I Learned

오늘은 어제 Filter에 이어 Interceptor에 대해 공부했다.


Interceptor

  • Dispatcher Servlet 전/후에 적용되어 요청과 응답을 참조하거나 가공하는 기능을 제공한다.

  • URL 패턴으로 대상을 구분해서 걸러낸다.

  • 자바의 기능인 filter와 다르게 스프링 프레임워크의 기능이다.
    스프링 Context 안에서 동작한다.
    스프링 내의 모든 bean 객체에 접근이 가능하다.

  • org.springframework.web.servlet의 HandlerInterceptor인터페이스를 구현한다.

  • Filter와 다르게 HttpServletRequest나 HttpServletResponse 객체를 제공받기 때문에 객체 자체를 조작할 수는 없다. 대신 내부적의 값을 조작할 수 있기 때문에 정보를 가공하기에 용이하다.

주 용도

  • 세부적인 보안 및 인증/인가 관련 작업
    (ex.특정 그룹의 사용자가 어떤 기능을 사용하지 못하게)
  • API 호출에 대한 로깅 또는 감사
  • 컨트롤러로 넘겨주는 데이터의 가공

Method

  • preHandle()
    컨트롤러가 호출되기 전 실행된다. boolean 반환타입으로, true면 다음 단계로 진행되고, false면 작업을 중단해 이후의 작업이 진행되지 않는다.

  • postHandle()
    컨트롤러가 호출 된 후 view 페이지 렌더링 전에 실행된다. 컨트롤러 하위계층에서 작업 중 예외가 발생하면 호출되지 않는다.

  • afterCompletion()
    view 렌더링까지 마치고 모든 작업이 완료된 후에 실행된다. 요청 중 사용한 리소스를 반환할 때 사용하기 적합하다. 컨트롤러 하위계층에서 작업 중 예외가 발생해도 무조건 호출된다.

구현 예시

로그인 한 유저만 컨트롤러에 접근하도록 인터셉터로 설정했다. preHandle를 써서 컨트롤러에 접근하기 전에 적용했다. (Spring Security로 구현하는게 더 적절하다고 생각하지만, 인터셉터를 구현해보기 위해 아래와 같은 방법을 써봤다.)

  • AuthInterceptor
@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;
  }
}
  • WebMvcConfig : @Component로 bean객체 등록이 된 인터셉터를 addPathPatterns를 통해 경로를 지정해 등록했다.
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {

  private final AuthInterceptor authInterceptor;

  //  interceptor를 등록
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(authInterceptor)
        .addPathPatterns("/post/**"); // 인터셉터 적용 경로를 지정
  }
}
profile
Backend Dev / Data Engineer

0개의 댓글