스타크래프트 케리어에서 나오는 공격하는 요격기가 interceptor입니다.
이처럼 어떠한 기능을 실행하기 전에 요격해서 실행을 할지 말지 막아주는 것을 interceptor라고 합니다.
그런데 filter와 interceptor, AOP는 어떠한 차이점이 있는지 간단히 알아보고 interceptor 예시를 보겠습니다.
Filter, Interceptor, AOP 차이
동작이 이루어지는 과정에서 그 동작의 전후로 공통적으로 처리해야 할 기능들이 존재합니다.
Logging, 보안, 로그인 인증, 인코딩 변환 등등이 있습니다.
중복을 줄이고자 이러한 기술들이 나왔는데요.
위의 세 가지가 어떤 차이가 있는지 알아보겠습니다.
일단 동작의 순서는
Filter - Interceptor - AOP - Controller - AOP - Interceptor - Filter
이러한 순서로 동작됩니다.
Filter
Filter는 일반적으로 스프링과 무관하게 전역적으로 처리해야 하는 작업들을 처리할 때 사용한다고 합니다.
Filter는 Spring이 실행되기 전에 실행되며 Tomcat과 같은 웹컨테이너 (WAS)에서 처리해 주게 됩니다.
Request / Response에 대한 조작이 가능합니다. (HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아서 처리하게 됩니다.)
사용 예시
- 공통된 보안 및 인증/인가 관련 작업(XSS방어)
- 이미지/데이터 압축 및 문자열 인코딩 변환 처리
- Spring과 분리되어야 하는 기능
- 모든 요청에 대한 로깅
Interceptor
로그인 체크, 권한체크, 프로그램 실행시간 계산작업 로그 확인 등의 작업을 하는 데 사용한다고 합니다.
Spring 프레임워크에서 제공하는 기능으로, 주로 컨트롤러의 메서드를 가로채고 처리하는 데 사용됩니다.
Spring MVC에서 HTTP 요청을 처리하는 컨트롤러의 메서드에 적용되어, 요청 전후에 특정 작업을 수행하도록 합니다.
사용 예시
- 세션 처리
- 세부적인 보안 및 인증/인가 공통 작업( 특정 사용자는 특정 기능을 사용 못하게 막음)
- API 호출에 대한 로깅
HttpServletRequest나 HttpServletResponse 등과 같은 객체를 제공받으므로 객체 자체를 조작할 수는 없습니다.
AOP
https://pabeba.tistory.com/192
이곳에 잘 설명해 놓았습니다.
저희가 이제 이번시간에 알아볼 것은 Interceptor 이기 때문에 이것에 대한 사용 방법을 보겠습니다.
Interceptor 사용 예시
이번 예시는 세션을 통해 로그인을 했는지 안 했는지 확인하고 로그인을 하지 않으면 막아버리고 세션이 있다면 통과하게 만드는 로그인 인증 Interceptor를 만들겠습니다.
먼저 동작을 하는 LoginCheckInterceptor를 만들겠습니다.
<LoginCheckInterceptor.java>
@Component
public class LoginCheckInterceptor implements HandlerInterceptor{
private Logger log=LoggerFactory.getLogger(getClass());
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session=request.getSession(false);
if(session==null||session.getAttribute("mvo")==null) {
log.warn("#인터셉터 체크: 비인증 상태 {} #",request.getRequestURI());
response.sendRedirect("/");
return false;
}
return true;// Handler(Controller) 실행
}
}
1. HandlerInterceptor는 Spring 프레임워크에서 제공하는 인터페이스입니다.
2. preHandle 메서드를 이용하여 지정한 메서드가 실행되기 전에 호출되는 메서드입니다.
3. HTTP 요청 객체, HTTP 응답 객체, 요청을 처리하는 핸들러 객체를 이용할 수 있습니다.
4. session이 있으면 true를 return 합니다.
5. session이 없다면 warn 로그를 보내주고 로그인 Form이 있는 페이지로 이동하고 false를 반환해 줍니다.
true가 반환되면 핸들러가 실행되는 것이고, false가 반환되면 Handler가 실행되지 않습니다.
그다음 Controller 메서드에 Interceptor 설정하는 법을 알아보겠습니다.
메소드에 Interceptor 설정
@Configuration
public class HandlerInterceptorConfigure implements WebMvcConfigurer{
private final LoginCheckInterceptor loginCheckInterceptor;
@Autowired
public HandlerInterceptorConfigure(LoginCheckInterceptor loginCheckInterceptor) {
super();
this.loginCheckInterceptor = loginCheckInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/","/home","/login","/registerMember*","/images/**","/css/**","/scripts/**");
}
}
1. 웹 애플리케이션의 MVC 구성을 커스터마이징 할 때 사용하는 WebMvcConfigurer를 구현하여 HandlerInterceptorConfigure 생성
2. 위에서 만든 LoginCheckInterceptor의 의존성 주입을 합니다.
3. addInterceptors를 이용하여 설정해 줍니다.
4. addPathPatterns를 통해 현재 경로와 하위의 모든 경로에 인터셉터를 적용한다고 작성합니다. ("/**")
5. excludePathPatterns를 통해 인터셉터 적용을 제외할 경로를 명시합니다.
이렇게 하고 세션을 삭제한 다음 로그인 인증이 필요한 메서드를 이용하면 어떤 결과가 나오는지 확인해 보겠습니다.
2023-07-21 00:21:41.340[0;39m [33m WARN[0;39m [35 m1277612776[0;39m [2m---[0;39m [2m[nio-7777-exec-7][0;39m [36m o.k.m.c.i.LoginCheckInterceptoro.k.m.c.i.LoginCheckInterceptor [0;39m [2m:[0;39m #인터셉터 체크: 비인증 상태 /findMemberById #
짜잔! 멤버를 찾는 메서드를 실행했는데, 비인증 log가 작성되면서 다시 로그인 페이지로 이동하게 됩니다!
차이점 요약
Interceptor와 Filter는 주소로 대상을 구분해서 걸러내야 하는 반면, AOP는 주소, 파라미터, 애노테이션 등 다양한 방법으로 대상을 지정할 수 있습니다.
AOP의 Advice와 HandlerInterceptor의 가장 큰 차이는 파라미터의 차이입니다.
Advice의 경우 JoinPoint나 ProceedingJoinPoint 등을 활용해서 호출합니다.
반면 HandlerInterceptor는 Filter와 유사하게 HttpServletRequest, HttpServletResponse를 파라미터로 사용합니다.
소감
아직 솔직히 이야기해서 filter, aop, interceptor 이 세 가지의 사용처가 정확하게 어떻게 다른지는 잘 모르겠지만
개념적인 차이점에 대해서는 확실하게 알아야겠습니다.
참조