-
Spring 인터셉터를 활용한 User-Agent 기반 접근 제어카테고리 없음 2025. 2. 4. 15:01반응형
Spring Interceptor로 특정 User-Agent 필터링 및 리디렉션하기
- 핵심 키워드: Spring Interceptor, User-Agent 검사, Request Filtering, Access Control
- 비슷한 개념: API Gateway에서 특정 User-Agent를 필터링하는 방식과 유사
1. 들어가며
웹 애플리케이션을 운영하다 보면 특정 클라이언트(User-Agent)만 접근을 허용하거나, 특정 User-Agent를 가진 요청을 별도의 페이지로 안내해야 하는 경우가 있습니다.
예를 들면:
✅ 앱 전용 페이지를 제공하고 싶을 때
✅ 특정 User-Agent를 가진 봇이나 크롤러를 차단하고 싶을 때
✅ 웹과 앱에서 다른 화면을 보여주고 싶을 때
이 글에서는 Spring MVC의 HandlerInterceptor를 활용하여 User-Agent를 검사하고, 특정 문자열이 없으면 다른 페이지로 리디렉트하는 방법을 소개하겠습니다.2. Spring Interceptor란?
HandlerInterceptor는 Spring MVC에서 제공하는 인터페이스로, 컨트롤러가 실행되기 전에 요청을 가로채어 처리할 수 있는 기능을 제공합니다.
주요 메서드는 다음과 같습니다:
• preHandle(): 컨트롤러 실행 전에 요청을 가로채는 메서드
• postHandle(): 컨트롤러 실행 후, 뷰 렌더링 전에 실행
• afterCompletion(): 모든 요청 처리가 끝난 후 실행
우리는 preHandle()을 활용하여 “User-Agent 헤더를 검사하고 특정 문자열이 없으면 리디렉트”하는 기능을 구현할 것입니다.3. User-Agent 검사 및 리디렉션 구현
3.1 UserAgentInterceptor 만들기
아래 코드처럼 HandlerInterceptor를 구현하여 특정 User-Agent를 체크하는 인터셉터를 만듭니다.import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class UserAgentInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// User-Agent 헤더 가져오기
String userAgent = request.getHeader("User-Agent");
// "LETTERAPP" 문자열이 포함되어 있는지 확인
if (userAgent == null || !userAgent.contains("LETTERAPP")) {
// 없으면 mainPage.do로 리디렉트
response.sendRedirect("mainPage.do");
return false; // 이후의 컨트롤러 처리를 중단
}
return true; // 정상적으로 진행
}
}3.2 Spring 설정 파일에 등록
Spring MVC에서 인터셉터를 사용하려면 WebMvcConfigurer를 구현한 설정 클래스에서 등록해야 합니다.import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserAgentInterceptor())
.addPathPatterns("/**"); // 모든 요청에 대해 적용
}
}4. 실행 결과
✅ User-Agent에 “LETTERAPP”이 포함되어 있는 경우
→ 정상적으로 요청을 처리
✅ User-Agent에 “LETTERAPP”이 없는 경우
→ mainPage로 리디렉트5. 응용 및 확장
이 방식을 활용하면 다양한 요구사항을 해결할 수 있습니다.
✔ 앱 전용 API 분리: 특정 User-Agent가 있는 경우 앱 API를, 없는 경우 웹 API를 호출하도록 설정 가능
✔ 크롤러 차단: User-Agent를 분석하여 검색 엔진 크롤러나 봇을 차단 가능
✔ 다중 User-Agent 지원: "LETTERAPP" 외에도 "MYAPP", "ANDROIDAPP" 등의 다양한 User-Agent를 허용 가능6. Spring Interceptor에서 예외 처리 추가하기
기본적으로 response.sendRedirect("mainPage.do")를 사용하면 클라이언트가 직접 302 Redirect 응답을 받아 이동하지만, Spring의 예외 처리 방식을 활용하면 좀 더 깔끔하게 처리할 수 있습니다.
여기서는 ModelAndViewDefiningException을 사용하여 리디렉션 대신 특정 뷰를 반환하도록 수정하겠습니다.
🔹 수정된 UserAgentInterceptor
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.ModelAndViewDefiningException;
public class UserAgentInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// User-Agent 헤더 가져오기
String userAgent = request.getHeader("User-Agent");
// "LETTERAPP" 문자열이 포함되어 있는지 확인
if (userAgent == null || !userAgent.contains("LETTERAPP")) {
// 리디렉트 대신 예외를 던져서 특정 뷰 반환
ModelAndView mav = new ModelAndView("redirect:/mainPage.do");
throw new ModelAndViewDefiningException(mav);
}
return true; // 정상 요청 처리
}
}
🔹 ModelAndViewDefiningException을 사용하는 이유
1. Spring MVC의 예외 처리 방식과 자연스럽게 통합
• 예외가 발생하면 Spring의 예외 처리 메커니즘에 따라 에러 페이지가 아닌 특정 뷰를 반환할 수 있음.
2. 리디렉트와 예외 처리를 깔끔하게 분리
• sendRedirect()는 직접 응답을 조작하는 방식이라 예외 처리가 어렵지만, ModelAndViewDefiningException을 던지면 인터셉터 내부에서 요청 흐름을 자연스럽게 제어 가능.
🔹 실행 흐름
1. “LETTERAPP”이 포함된 요청 → 정상적으로 컨트롤러 실행
2. “LETTERAPP”이 없는 요청 → "redirect:/mainPage.do"를 반환하여 자동 리디렉트
3. 예외 발생 시
• DispatcherServlet이 ModelAndViewDefiningException을 처리하여 지정된 뷰(mainPage.do)로 이동
🔹 추가 응용 (커스텀 에러 페이지로 보내기)
만약 mainPage.do가 아니라 에러 메시지가 포함된 별도 에러 페이지로 보내고 싶다면?
if (userAgent == null || !userAgent.contains("LETTERAPP")) {
ModelAndView mav = new ModelAndView("errorPage"); // errorPage.jsp or errorPage.html
mav.addObject("message", "올바른 앱에서 접근해주세요."); // 에러 메시지 전달
throw new ModelAndViewDefiningException(mav);
}
이렇게 하면 에러 메시지를 포함한 화면을 보여줄 수도 있습니다.
✅ sendRedirect() 대신 ModelAndViewDefiningException을 사용하면 Spring의 예외 처리 방식과 자연스럽게 연동 가능
✅ 특정 뷰로 리디렉트할 뿐만 아니라, 에러 메시지를 포함하는 것도 가능
✅ preHandle()에서 예외를 던지면 컨트롤러가 실행되지 않고 바로 뷰 렌더링이 가능
이제 Spring Interceptor에서 더 깔끔하게 User-Agent를 검사하고 리디렉트할 수 있습니다!
이번 글에서는 Spring Interceptor를 이용하여 User-Agent를 검사하고 특정 조건을 만족하지 않으면 리디렉트하는 방법을 살펴봤습니다.
✅ HandlerInterceptor를 사용하면 컨트롤러 실행 전에 요청을 제어할 수 있다.
✅ preHandle()에서 User-Agent 헤더를 확인하고 원하는 문자열이 없으면 리디렉트할 수 있다.
✅ WebMvcConfigurer를 활용해 인터셉터를 쉽게 적용할 수 있다.반응형