[스프링부트] 34. 인터셉터

백하림's avatar
Apr 23, 2025
[스프링부트] 34. 인터셉터
notion image

✅ WebMvcConfig – 인터셉터 설정 정리

📌 목적

Spring Boot 애플리케이션에서 인증이 필요한 경로에 대해 로그인 여부를 체크하기 위한 인터셉터(LoginInterceptor)를 등록하고 설정한다.
package shop.mtcoding.blog._core.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import shop.mtcoding.blog._core.interceptor.LoginInterceptor; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { WebMvcConfigurer.super.addInterceptors(registry); registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/user/**") .addPathPatterns("/board/**") .addPathPatterns("/love/**") .addPathPatterns("/reply/**") .addPathPatterns("/api/**") .excludePathPatterns("/board/{id:\\d+}"); // 정규 표현식 } }
💡

🔍 상세 설명

1. @Configuration

  • 해당 클래스가 스프링 설정 클래스임을 나타낸다.
  • 스프링 부트 실행 시 이 설정이 자동으로 등록됨.

2. WebMvcConfigurer

  • Spring MVC의 설정을 커스터마이징할 수 있도록 해주는 인터페이스.
  • 그 중 addInterceptors() 메서드를 오버라이드하여 인터셉터를 등록한다.

3. addInterceptor()

  • 인증 확인용 LoginInterceptor를 등록함.
  • 지정된 URL 경로에 대해 작동하도록 설정.

4. addPathPatterns(...)

  • 인터셉터가 적용될 URL 패턴들 지정
  • 예: /user/**, /board/**, /love/**, /reply/**, /api/**

5. excludePathPatterns(...)

  • 인터셉터에서 제외할 경로 지정
  • /board/{id:\d+}는 정규 표현식을 이용해 숫자만 허용하는 게시글 상세 페이지
    • 예: /board/1, /board/25 등은 예외 처리됨 → 로그인 없이 접근 가능

✅ LoginInterceptor – 로그인 인증 인터셉터

📌 역할

HTTP 요청이 컨트롤러에 도달하기 전에 로그인 여부를 검사하여, 비로그인 사용자의 접근을 차단한다.
package shop.mtcoding.blog._core.interceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import shop.mtcoding.blog._core.erorr.ex.Exception401; import shop.mtcoding.blog._core.erorr.ex.ExceptionApi401; import shop.mtcoding.blog.user.User; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); System.out.println("uri: " + uri); HttpSession session = request.getSession(); User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) { if (uri.contains("/api")) { throw new ExceptionApi401("인증이 필요합니다"); // response.setStatus(401); // response.setHeader("Content-Type", "application/json"); // PrintWriter out = response.getWriter(); // Resp<?> resp = Resp.fail(401, "인증이 필요합니다"); // ObjectMapper mapper = new ObjectMapper(); // String responseBody = mapper.writeValueAsString(resp); // out.println(responseBody); // return false; } else { throw new Exception401("인증이 필요합니다"); // response.setStatus(401); // response.setHeader("Content-Type", "text/html"); // PrintWriter out = response.getWriter(); // out.println(Script.href("인증이 필요합니다", "/login-form")); // return false; } } return true; } }
💡

🔍 상세 설명

1. HandlerInterceptor 구현

  • Spring MVC의 요청 흐름에서 컨트롤러 진입 전에 개입할 수 있는 인터셉터를 정의한다.
  • preHandle() 메서드는 컨트롤러 진입 전 호출됨.

2. request.getRequestURI()

  • 현재 요청한 URI(주소 경로) 를 가져온다.
  • 로그 출력 등을 위해 사용하며, 이후 "/api" 포함 여부 판단에 활용됨.

3. HttpSession 검사

  • request.getSession()을 통해 현재 세션에 접근.
  • 세션에서 sessionUser를 꺼내 로그인 여부를 확인한다.
  • 세션이 비어있으면 로그인되지 않은 상태.

4. 로그인하지 않은 경우 처리

  • 요청 URI에 /api가 포함되어 있으면 → API 요청으로 판단하고 ExceptionApi401 예외 발생
  • 그렇지 않으면 일반 웹 요청으로 간주하고 Exception401 예외 발생

5. 예외 클래스에 따라 다른 방식으로 처리

  • ExceptionApi401: JSON 응답 (비동기)
  • Exception401: 리다이렉션 응답 (동기)

💡 핵심 포인트

  • 하나의 인터셉터에서 API 요청과 웹 요청을 분리 처리한다.
  • 예외를 던지는 방식으로 인증 실패 시 응답 처리를 일원화함 (전역 예외 핸들러에서 처리 가능).
  • 요청 URI를 통해 어떤 요청인지 판별하는 로직이 단순하면서도 효과적임.
Share article

harimmon