오답노트
[Spring] Interceptor 본문
Interceptor
Intercepter는 FIlter와 매우 유사한 형태로 존재하지만, 차이점은 Spring Context에 등록된다는 점이다.
AOP와 유사한 기능을 제공 할 수 있고, 주로 인증 단계를 처리하거나, Logging을 하는데 사용한다.
이를 전/후처리 함으로써 Service business logic과 분리 시킨다.
import com.example.interceptor.annotation.Auth;
import com.example.interceptor.exception.AuthException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURI();
URI uri = UriComponentsBuilder.fromUriString(request.getRequestURI()).query(request.getQueryString()).build().toUri();
log.info("req url : {}",url);
boolean hasAnnotation = checkAnnotation(handler, Auth.class);
log.info("has Annotation : {}",hasAnnotation);
// 나의 서버는 모두 public으로 동작하는데
// 단, Auth 권한을 가진 요청에 대해서는 ...
if(hasAnnotation){
// 권한 체크
String query = uri.getQuery();
log.info("query : {}",query);
if(query.equals("name=steve")){
return true;
}
throw new AuthException();
}
return true;
}
private boolean checkAnnotation(Object handler, Class clazz){
// resorce, js, html
if( handler instanceof ResourceHttpRequestHandler){
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
if(null != handlerMethod.getMethodAnnotation(clazz) || null != handlerMethod.getBeanType().getAnnotation(clazz)){
return true;
}
return false;
}
}
HandlerInterceptor 인터페이스를 상속받아 Interceptor 클래스를 생성한다.
preHandle 를 Override 하여 권한과 같이 체크할 항목에 대한 로직을 구현하고, 절차를 다 정상적으로 수행했으면 true, 아니면 false를 반환한다.
import com.example.interceptor.Interceptor.AuthInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@RequiredArgsConstructor
public class MvcConfig implements WebMvcConfigurer {
private final AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor).addPathPatterns("/api/private/*");
}
}
그리고 WebMvcConfigurer 를 상속 받는 Config 클래스를 만들어 위에서 만든 Interceptor 클래스를 등록한다.
Config 클래스에 Interceptor 멤버 변수를 선언하고 addInterceptors를 Override하여 위에서 만든 Interceptor클래스가 어떤 주소에서 동작하게 할지 설정한다.
'Java > Spring' 카테고리의 다른 글
[Spring] Server to Server (0) | 2023.07.14 |
---|---|
[Spring] 비동기 처리 (Async) (0) | 2023.07.14 |
[Spring] Filter (0) | 2023.07.14 |
[Spring] Exception과 Validation (0) | 2023.07.14 |
[Spring] Exception (0) | 2023.07.14 |