본문 바로가기

BackEnd/Spring

[Spring] Interceptor는 무엇인가? Security와 Filter의 차이점은 무엇이고, 언제 사용할까?

안녕하세요 인포돈 입니다.


 

 Spring을 학습하다 보면, 우리는 로그인 구현하기 위해서 Security를 보통 처음 접하게 된다. Security를 통해서 들어오는 요청을 걸러내, 올바른 요청만 Controller에 도착을 할 수 있도록 만들어 로그인 기능을 구현하게 된다. 그렇다면, 우리는 Interceptor와 Security, Filter 3가지에 대해서 파 해치고 Interceptor에 대해 익혀보자.


Security와 Filter란?

 Security에 대한 설명은 정말 무수히 많은 블로그에 정리가 되어있다. 나는 이러한 Security에 대해서는 아주 간략히 접하고 넘어갈 볼 것이다. Security는 사용자의 '인증'과 '권한'에 대한 부분은 Filter의 흐름에 따라 처리하는 Spring의 하위 프레임 워크라고 생각하면 된다.

 

 좀 더 우리에게 와닿게 표현한다면, Security의 말 그대로 사용자를 인증하여 해당 서비스에 어느 정도까지 활용을 할 수 있을지 권한을 부여해 준다고 생각하면 된다. 아주 유명한 예로 바로 로그인이다.

 

 로그인을 통해서, 사용자를 인증하고 일반 사용자가 활용할 수 있는 서비스들을 이용할 권한을 준다. (로그인을 안 하면, 메일을 보낼 수 없고, 관리자로 로그인을 안 하면, 사용자를 관리할 수 없듯이) 이러한 서비스를 할 수 있도록 도와주는 하위 프레임 워크이다.

 

 그러면 이게 도대체 Filter와 InterCeptor와 무슨 관계인가?라는 의문이 들 것이다. 그것은 아래의 내용에 이어서 들어가 보면서 이해해보자

 

  앞선 설명에서 Security는 Filter의 흐름대로 동작한다고 설명했었다. 그렇다면 Filter는 무엇이고, 어떠한 흐름이기에 Security가 이를 활용하지? 이를 이해해보아야 한다.

 

 Filter를 이해하기 전에 우리는 Dispatch Servlet이 왜 생겨 났는지에 대해서 이해했다면, 아주 쉽게 이해할 수 있을 것이다. 기본적으로 Dispatch Servlet은 공통 관심사를 분리하여, 미리 앞단에서 처리함으로써 후단에서의 반복적인 로직을 제거할 수 있어 유지/보수/개발에 모두 효율적이어서 사용되었다. 이와 똑같다.

 

 Filter는 사용자가 받기 전에 앞단에서 미리 걸러주는 Filter역할을 하는 로직이라고 생각하면 된다.

 

  Security 이전에는 Filter와 뒤에 설명할 Interceptor를 통해서 로그인을 통해 들어갈 수 있는 곳과 들어갈 수 없는 곳을 미리 사전에 걸러 주었다. 여기서 Filter에서 발전한 것이 바로 Security이다. ( Filter의 기능뿐만 아니라 Security에는 무수히 많은 보안 과련 로직들이 담겨 있다.)

 

 Filter의 기본 동작 과정은 아래와 같다.


Interceptor 란?

 인터셉터는 앞선 Filter와 굉장히 유사한 동작을 보여준다. 빠른 이해를 위해서 흐름을 먼저 소개해 보면 아래와 같다.

 

 Filter와 다르게 Dispatcher 뒷단에서 동작한다. 똑같이 Controller에 도착하기 전에 미리 사전 작업을 할 수 있다는 점이다. 그러면 도대체 왜 이렇게 2개를 만들어서 사용하는 것일까? 무슨 차이인지 이해를 하고 사용을 해야 한다.

 

아주 잘 정리된 표가 있어 가져와 보았다.

출처 :  https://mangkyu.tistory.com/173

 가장 큰 차이점은 바로 Request/Reponse 조작 기능 여부이다. 여기서 말하는 조작 가능 여부는 내부 상태를 변경하다는 것이 아니라 다른 객체로 바꿔 친다는 의미이다.

 

 FIlter의 경우 doFilter를 통해 request, response를 넘겨줄 수 있다. 그러나 Interceptor의 경우 Boolean만 넘겨줄 수 있다는 점이다. 즉 새로운 response나 request를 정의하여 넘겨줄 수 없다는 의미가 된다.

 

 현시점에서는 그렇게 와닿지 않을 수 있지만, 사용자의 요청과 응답을 새롭게 작성해야 되는 서비스가 있다는 점만 알아두고 넘어가자.

 

 또 다른 큰 차이점은 관리되는 컨테이너의 위치이다. 필터의 경우 웹 컨테이너에서 관리가 된다. 즉, Spring과 독립적으로 작동될 수 있다는 점이다. 다수의 서버를 운영하게 될 때 Interceptor보다는 필터를 활용하는 방식이 더 좋다는 의미가 된다.

 

 대표적으로 Filter와 Interceptor가 사용되는 부분은 아래와 같다.

 Filter

 - 인증/인가 관련 작업

 - 요청에 대한 로깅 검사

 - 이미지/데이터 압축 및 문자열 인코딩

 - Spring과 분리되어야 하는 기능

Interceptor

 - 인증/인가 관련 작업

 - API 호출에 대한 로깅 검사

 - Controller로 넘겨주는 데이터 가공

 

 * 아직까지 언제 Filter를 사용하고 Interceptor를 사용해야 하는지 감이 안 올 수 있는데, 현시점에서 아주 간단히 관리되는 컨테이너에 따라서 원하는 서비스를 활용하면 된다. (보통의 경우 Security를 활용한 인증/인가를 많이 활용하긴 한다.)


 간단히 Interceptor를 활용하는 방식을 알아보자

 

 - 인터셉터 생성

@Component
@Slf4j
public class BeforeActionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("BeforeActionInterceptor::preHandle 실행됨");

        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}

간단한 인터셉터를 생성한다. 이때, preHandle 말고도 다양한 메서드가 존재한다. 이는 인터셉터를 활용하기에서 좀 더 다뤄보자

 

 - 인터셉터 등록하기 (기본적으로 생성만 해서는 어떤 요청에 동작해야 하는지 모른다.)

@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {

    private final BeforeActionInterceptor beforeActionInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry){
        InterceptorRegistration ir;

        ir = registry.addInterceptor(beforeActionInterceptor);
        ir.addPathPatterns("/**");
        ir.excludePathPatterns("/favicon.ico");
        ir.excludePathPatterns("/resource/**");
        ir.excludePathPatterns("/gen/**");
        ir.excludePathPatterns("/error");
    }
}

 아주 간단하다. 이미 만들어져 있는 InterceptorRegistration에다가 내가 만든 befroeActionInterceptor를 추가한 후, 허용할 url을 적용만 한다면, 해당 위치에 들어가기 전에 반듯이 beforeActionInterceptor가 동작하게 된다.

 

 * 만약 2개 이상의 인터셉터를 등록하게 된다면, InterceptorRegistration에 등록한 순서대로 동작한다.

 

 

'BackEnd > Spring' 카테고리의 다른 글

[Spring] Gradle과 Maven의 차이점 및 트렌드  (0) 2022.05.23