Interceptors

2024. 10. 14. 22:09Spring Framework/Web on Servlet Stack

Spring MVC에서 Interceptor는 incoming HTTP 요청과 outgoing 응답에 대해 로직을 적용할 수 있는 강력한 메커니즘입니다. 이를 통해 컨트롤러에 요청이 도달하기 전에 요청을 가로채거나, 컨트롤러에서 응답을 처리한 후 추가 로직을 수행할 수 있습니다. Interceptor는 주로 로깅, 감사(auditing), 요청/응답 객체를 수정하는 작업에 사용됩니다.

1. Interceptor의 작동 방식

Interceptor는 Servlet Filter와 비슷하게 작동하지만, Spring Web Application Context와 더 밀접하게 통합됩니다. Interceptor는 전역적으로 등록되어 모든 요청에 적용되거나, 특정 URL 패턴에만 제한적으로 적용할 수 있습니다.

주요 개념:

  • Pre-Handle (preHandle): 이 메서드는 컨트롤러의 메서드가 호출되기 전에 실행됩니다. 이 메서드가 true를 반환하면 요청은 컨트롤러로 진행됩니다. false를 반환하면 요청이 중단되고 즉시 응답이 반환됩니다.
  • Post-Handle (postHandle): 이 메서드는 컨트롤러 메서드가 호출된 후, 하지만 뷰가 렌더링되기 전에 호출됩니다.
  • After-Completion (afterCompletion): 이 메서드는 뷰가 렌더링된 요청 처리가 완전히 끝난 후에 호출됩니다.

2. Java Configuration에서 Interceptor 등록

Java 기반의 Spring 구성에서 Interceptor는 WebMvcConfigurer 인터페이스를 구현하고, addInterceptors() 메서드를 오버라이드하여 등록할 수 있습니다.

예시:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // LocaleChangeInterceptor를 추가하여 각 요청에서 locale을 변경할 수 있게 함
        registry.addInterceptor(new LocaleChangeInterceptor());

        // ThemeChangeInterceptor를 추가하되, /admin 경로는 제외
        registry.addInterceptor(new ThemeChangeInterceptor())
                .addPathPatterns("/**")  // 모든 경로에 적용
                .excludePathPatterns("/admin/**");  // /admin 경로는 제외
    }
}

이 예시에서:

  • LocaleChangeInterceptor: 이 Interceptor는 요청 파라미터를 기반으로 애플리케이션의 locale을 동적으로 변경할 수 있게 합니다 (예: ?locale=...).
  • ThemeChangeInterceptor: 이 Interceptor는 요청 파라미터를 사용하여 애플리케이션의 테마를 변경할 수 있게 합니다.

설명:

  • registry.addInterceptor(): Interceptor를 등록합니다.
  • .addPathPatterns("/**"): 모든 경로에 Interceptor를 적용합니다.
  • .excludePathPatterns("/admin/**"): /admin/** 경로는 Interceptor에서 제외됩니다.

3. Interceptor의 보안 한계

Spring에서는 Interceptor를 보안 계층으로 사용하는 것에 대해 주의를 권고합니다. Interceptor는 Spring MVC의 Path 매칭 방식과 일치하지 않을 가능성이 있기 때문입니다. 보안은 애플리케이션에서 매우 중요한 요소이므로, Spring Security를 사용하거나, Servlet Filter 체인과 같은 더 강력한 보안 방법을 사용하는 것이 좋습니다. 이러한 방법은 요청 처리 초기에 적용되므로 보안과 관련된 로직을 더 일관되고 안전하게 적용할 수 있습니다.

Interceptor는 특정 보안 작업을 처리할 수 있지만, 이러한 한계를 인지하고 설계해야 합니다. 보안 작업은 가능하면 Servlet Filter를 통해 처리하는 것이 좋습니다.

4. XML Configuration에서의 Interceptor

XML 기반의 Spring 구성에서는 Interceptor가 MappedInterceptor 빈으로 선언되며, 이는 모든 HandlerMapping 빈에서 자동으로 감지됩니다(다른 프레임워크의 HandlerMapping도 포함). 이는 Java Configuration에서 Interceptor가 Spring MVC가 관리하는 HandlerMapping 빈에만 전달되는 것과는 다릅니다.

Spring MVC와 다른 프레임워크의 HandlerMapping에서 동일한 Interceptor를 재사용하려면:

  • Interceptor를 MappedInterceptor 빈으로 선언하거나,
  • Java Configuration과 다른 HandlerMapping 빈 모두에 Interceptor를 수동으로 등록해야 합니다.

보편적으로 많이 사용하는 Interceptor

  1. LocaleChangeInterceptor
    • 애플리케이션의 locale을 변경하는 데 사용됩니다. 사용자가 요청 파라미터를 통해 locale(언어 설정)을 동적으로 변경할 수 있습니다.
    • 예시: ?locale=en_US.
  2. ThemeChangeInterceptor
    • 요청 파라미터를 기반으로 애플리케이션의 테마를 변경할 수 있습니다.
    • 예시: ?theme=dark.
  3. HandlerInterceptorAdapter
    • Spring이 제공하는 기본 클래스이며, 이를 확장하여 preHandle, postHandle, afterCompletion 메서드를 오버라이드해 커스텀 Interceptor를 구현할 수 있습니다.
  4. WebContentInterceptor
    • HTTP 응답 캐싱과 헤더를 제어하는 데 사용됩니다. 동적 웹 콘텐츠의 브라우저 캐싱을 관리할 때 유용합니다.
    WebContentInterceptor interceptor = new WebContentInterceptor();
    interceptor.setCacheSeconds(0);  // 캐싱 비활성화
    interceptor.setRequireSession(true);  // 특정 페이지에 대해 세션 요구
  5. MetricsInterceptor (Custom)
    • 들어오는 요청에 대한 성능 지표를 수집하는 커스텀 Interceptor입니다. 요청 처리에 걸린 시간을 추적하고 성능 모니터링을 위해 로그로 남기거나 저장할 수 있습니다.
  6. LoggingInterceptor (Custom)
    • 요청과 응답을 로깅하는 커스텀 Interceptor입니다. 디버깅 또는 감사(Auditing) 목적으로 유용하며, 요청 URL, HTTP 헤더, 요청 본문, 응답 상태 등을 로깅할 수 있습니다.

Servlet Filter와 Spring Security

Spring에서 언급한 것처럼, Interceptor는 다양한 공통 관심사(cross-cutting concerns)를 처리하는 데 유용하지만, 보안 목적으로 사용하기에는 적합하지 않습니다. Interceptor는 Spring의 HandlerMapping과 연결되어 있어, 요청 수명 주기에서 더 낮은 수준에 있는 Servlet Filter보다 나중에 실행됩니다. 보안 작업은 요청 초기에 적용되어야 하므로 Spring SecurityServlet Filter를 사용하는 것이 더 적합합니다.

Servlet Filter와 Interceptor의 차이점

특징 Servlet Filter Spring MVC Interceptor
요청 처리 시점 모든 incoming 요청에 대해 초기에 적용됨 요청이 핸들러에 매핑된 후에 적용됨
범위 Spring MVC 외부에서도 동작 가능 (정적 리소스 등) Spring MVC 내에서만 동작
사용 목적 보안, 로깅, 요청 수정 로깅, 커스텀 처리, 모델 수정
보안 보안에 적합 (예: 인증, 인가) 보안에는 적합하지 않음

결론

Interceptor는 Spring MVC에서 매우 유용한 기능으로, 요청과 응답에 대해 커스텀 로직을 적용할 수 있습니다. 주로 로깅, 감사, locale/테마 변경, 성능 모니터링 등에 사용됩니다. 그러나, 보안 목적으로는 적합하지 않으며, 보안 관련 작업은 Spring SecurityServlet Filter를 사용하는 것이 좋습니다.

만약 HTTP 요청에 로깅이나 성능 지표 수집과 같은 공통 관심사를 적용하고자 한다면 Interceptor는 훌륭한 도구입니다. 하지만 보안과 관련된 기능이 필요하다면, 더 강력하고 유연한 Spring Security 프레임워크를 사용하는 것이 가장 좋습니다.

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

Message Converters  (0) 2024.10.15
Content Types  (0) 2024.10.15
Validation  (0) 2024.10.14
Type Conversion  (0) 2024.10.14
MVC Config API  (0) 2024.10.14