Filter와 Interceptor는 어떻게 작동할까 ? #15
Replies: 3 comments
-
Filter나 Interceptor모두 공통 관심사를 처리하기 위한 목적이 있지만, Filter는 웹 요청/응답에 대한 관심사 Interceptor는 Controller에 호출 맥락에 따른 관심사의 차이를 가진다 생각합니다. Filter도 url패턴으로 특정 요청에만 동작하도록 할 수 있습니다. 그러나, Handler가 정해진 뒤 수행하는 Interceptor가 처리하는 게 역할과 책임 측면에서 낫다고 생각합니다! Filter는 Spring MVC가 진입하기 전, 웹 요청/응답에 대한 공통 관심사를 다룹니다. 요청/응답 로깅, 요청 인코딩, 비정상 요청 차단 etc.. Interceptor는 HandlerMapping으로 Handler가 정해진 뒤 실행되므로, 호출할 Controller가 정해진 상태로 Interceptor가 실행됩니다. Filter는 Servlet Container가 관리하는 FilterChain이라는 체인으로 동작합니다. Interceptor는 HandlerExecutionChain으로 동작합니다. |
Beta Was this translation helpful? Give feedback.
-
|
Filter와 Interceptor는 모두 여러 API에 반복되는 공통 관심사를 컨트롤러 밖에서 처리하기 위해 존재한다고 생각합니다. 둘의 가장 큰 차이는 동작 위치입니다. Filter는 서블릿 영역의 가장 바깥에서 동작해 요청 흐름으로 보면 Filter는 스프링 MVC보다 앞단에서 처리해야 하는 인코딩, 보안, 로깅 같은 넓은 범위의 처리에 적합하고, 특히 이번 미션의 인증 관점에서는 Interceptor를 “문지기”처럼 사용해 요청을 통과시킬지 막을지 판단하고, Filter는 어떤 개념인가?Filter는 서블릿 스펙에서 제공하는 요청/응답 전/후처리 장치라고 이해했습니다. HTTP 요청 Filter는 Spring MVC보다 앞단에 있기 때문에, 예를 들면 아래와 같은 작업이 어울립니다.
즉, Filter는 “이 요청이 어떤 컨트롤러로 갈지”보다는, Filter는 어떻게 동작하나요?Filter는 보통 doFilter()를 통해 동작합니다. 핵심은 chain.doFilter(request, response)를 호출하느냐입니다. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { } chain.doFilter()를 호출하면 다음 Filter 또는 DispatcherServlet으로 요청이 넘어갑니다. 반대로 특정 조건에서 chain.doFilter()를 호출하지 않으면 요청 흐름을 중간에서 끊을 수 있습니다. 즉, Filter는 요청을 다음 단계로 넘길지 말지 결정할 수 있고, 요청과 응답을 감싸거나 조작할 수도 있습니다. 다만 Filter는 Spring MVC 바깥쪽에 있기 때문에, 컨트롤러 메서드 정보나 HandlerMethod 같은 Spring MVC의 세부 정보를 활용하기에는 Interceptor보다 덜 적합하다고 생각합니다. Interceptor는 어떤 개념인가?Interceptor는 Spring MVC에서 컨트롤러 호출 전후에 끼어들 수 있는 장치라고 이해했습니다. HTTP 요청 Interceptor는 Spring MVC 안에서 동작하기 때문에, 그래서 인증 여부 확인이나 경로 기반 접근 제어처럼 Spring MVC 요청 처리 흐름과 밀접한 공통 로직에 적합하다고 생각합니다. 이번 미션 기준으로는 Interceptor를 아래처럼 이해할 수 있을 것 같습니다. 예를 들어 로그인하지 않은 사용자가 내 예약 조회 API를 호출하면 Interceptor에서 먼저 막을 수 있습니다. Interceptor는 어떻게 동작하나요?Interceptor는 대표적으로 세 시점에 개입할 수 있습니다.
인증 확인에서는 주로 preHandle()을 사용합니다. @Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler
) {
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loginMemberId") == null) {
response.setStatus(401);
return false;
}
return true;
}여기서 true를 반환하면 컨트롤러로 요청이 넘어가고, false를 반환하면 요청 흐름이 중단됩니다. 즉, Interceptor는 컨트롤러 앞에서 요청을 검사하고, 통과 여부를 결정하는 역할을 할 수 있습니다. Filter와 Interceptor는 왜 존재하나요?둘 다 존재하는 이유는 공통 관심사를 컨트롤러에서 분리하기 위해서라고 생각합니다. 예를 들어 모든 컨트롤러 메서드마다 아래와 같은 코드를 반복한다고 생각해볼 수 있습니다. 이 방식은 문제가 있습니다.
Filter나 Interceptor를 사용하면 이런 반복 로직을 한 곳으로 모을 수 있습니다. 컨트롤러는 요청을 받아 비즈니스 흐름을 호출하는 데 집중하고, 즉, 존재 이유는 단순히 “중간에 끼어들기 위해서”가 아니라, Filter와 Interceptor의 차이가장 큰 차이는 동작 위치와 다룰 수 있는 정보의 범위라고 생각합니다.
Filter는 더 바깥쪽에서 넓게 동작하고, 그래서 “HTTP 요청 자체를 다뤄야 하는가?”에 가까우면 Filter, 이번 선택 미션에서 Interceptor를 어디에 쓰면 좋을까?이번 미션에서는 Interceptor를 인증 여부 확인에 사용하기 적절하다고 생각합니다. 예를 들어 내 예약 조회, 예약 생성, 예약 취소 같은 API는 로그인한 사용자만 접근해야 합니다. 이때 각 컨트롤러마다 로그인 여부를 확인하기보다, Interceptor에서 먼저 막을 수 있습니다. 로그인 안 함 반대로 로그인한 사용자는 Interceptor를 통과하고, 이후 컨트롤러에서 현재 사용자 정보가 필요하면 ArgumentResolver가 @LoginMember 파라미터를 채워줄 수 있습니다. @GetMapping("/reservations/mine")
public List<ReservationResponse> myReservations(@LoginMember Member member) {
return reservationService.findMyReservations(member.getId());
}이렇게 보면 역할이 나뉩니다. Interceptor = 로그인 여부를 확인하고 요청을 통과시킬지 결정 즉, Interceptor와 ArgumentResolver는 경쟁 관계가 아니라 분업 관계라고 생각합니다. 인증과 인가는 같은 위치에서 처리해야 할까?저는 인증과 인가는 처리 위치가 다를 수 있다고 생각합니다. 인증은 “로그인했는가?”를 확인하는 것입니다. 이 정보는 세션이나 토큰만 보면 알 수 있기 때문에 Interceptor에서 처리하기 좋습니다. 세션에 loginMemberId가 있는가? 반면 인가는 “이 사용자가 이 리소스를 다룰 권한이 있는가?”를 확인하는 것입니다. 예를 들어 매장 매니저가 자기 매장 예약만 관리할 수 있는지 판단하려면, 현재 사용자뿐 아니라 접근하려는 예약 데이터도 조회해야 합니다. 현재 로그인한 매니저의 storeId 이런 판단은 단순히 요청 경로나 세션만 보고 결정하기 어렵습니다. 따라서 거친 넓은 범위 수준의 인가, 예를 들어 /admin/**은 관리자만 접근 가능하다는 정도는 Interceptor에서 처리할 수 있지만, 정리정리하면 저는 이렇게 이해했습니다.
결론적으로 이번 미션에서는 Interceptor를 인증의 “문지기”로 사용하고, |
Beta Was this translation helpful? Give feedback.
-
어떤 개념인가요 ?Filter와 Interceptor는 둘다 요청을 가로채어 공통작업을 처리하기 위한 기술입니다. 하지만 작동 위치가 서로 다르기 때문에 서로 다른 레벨의 기술 입니다. Filter는 MVC 이전의 서블렛 레벨에서 작동하며, 스프링이 아닌 웹 Servlet 스펙 기반 기술입니다. 그래서 MVC 레벨 이전의, 즉 DispatcherServlet 이전에 작동하기 때문에 모든 요청에 대해 처리할 수 있으며, MVC 핵심 로직의 앞단에 넓은 범위의 처리에 보통 사용합니다. 그와 반면에 Interceptor는 Spring MVC가 제공하는 기술이며, Controller 실행 전,후를 제어할 수 있습니다. 따라서 Spring MVC 로직과 관련된 처리가 필요한 경우 Interceptor를 사용할 수 있습니다. 특히 매핑될 컨트롤러가 정해진 이후 실행되는 기술이기 때문에 컨트롤러의 실행 맥락과 연관되는 경우에 사용하는 것이 적절하다고 생각합니다. 웹 서버 구조도
선택 기준작동 위치가 다르기 때문에, 해당 공통작업이 언제 처리되는지를 먼저 고려해보는 것이 중요합니다. 예를 들어, 보안의 경우, 인증되지 않은 사용자는 MVC 영역인 컨트롤러에 진입하면 안되기 때문에, 보안 작업은 가장 앞단인 Filter 레벨에서 수행해야 합니다.(스프링 시큐리티도 이런 이유로, Interceptor가 아닌 Filter를 사용합니다.) 그리고, 작업의 종류를 먼저 분류하는 것도 하나의 기준이 될 수 있습니다. 예를 들어, 인증 인가, 로깅, 사용자 정보 처리와 같은 MVC 로직과 연관된 경우 인터셉터가 적절하며, CORS 설정이나 Request 매핑과 같은 웹레벨의 작업 처리는 필터가 더 적절합니다. 추가학습이번 주차에 예외처리에 대해 학습해 보았으니, 필터 단계에서 발생하는 예외를 어디서 처리할지 고민해보는 것도 좋을 것 같습니다! |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
Beta Was this translation helpful? Give feedback.
All reactions