BE/SpringBoot

[Spring Boot] Spring Boot에서 Interceptor 구현하기

콩다영 2024. 5. 21.
728x90

 

Spring Boot 애플리케이션에서 Interceptor는 HTTP요청을 가로채고 처리할 수 있는 강력한 도구입니다.

이를 통해 인증, 권한 부여, 로깅, 공통 기능 등을 중앙 집중화하여 관리할 수 있습니다. 

인터셉터를 사용하여 로그인 확인 및 관리자 권한 확인을 구현하는 방법을 예제코드와 함께 정리하겠습니다 !

 

 

Interceptor란?

Spring의 Interceptor는 서블릿 필터와 유사하지만, 더 세밀하게 동작합니다.

HTTP 요청이 컨트롤러에 도달하기 전에 이를 가로채고, 응답이 클라이언트에 전송되기 전에 조작할 수 있습니다.

 

Interceptor는 HandlerInterceptor 인터페이스를 구현하여 정의합니다.

이 인터페이스에는 다음과 같은 세 가지 주요 메서드가 있습니다.

  • preHandle() : 컨트롤러에 요청이 도달하기 전에 호출됩니다.
  • postHandle() : 컨트롤러가 요청을 처리한 후, 뷰가 렌더링 되기 전에 호출됩니다.
  • afterCompletion() : 뷰가 렌더링 되고 응답이 클라이언트에 전송된 후에 호출됩니다.

 

 

예제코드

[ 로그인 확인 Interceptor ]

package com.example.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

public class LoginCheckInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(LoginCheckInterceptor.class);
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
        logger.info("LoginCheckInterceptor 시작!");
        
        // 사용자 세션에서 로그인 정보 가져오기
        Object loginUser = request.getSession().getAttribute("LOGIN_USER");
        
        if (loginUser == null) {
            logger.warn("로그인이 필요합니다.");
            response.sendRedirect("/login");
            return false;
        }
        
        return true;
    }
}

 

[ 관리자 권한 확인 Interceptor ]

package com.example.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

public class AdminCheckInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(AdminCheckInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        logger.info("AdminCheckInterceptor 시작!");

        // 사용자 세션에서 로그인 정보 가져오기 (예시)
        User loginUser = (User) request.getSession().getAttribute("LOGIN_USER");

        if (loginUser == null || !"ADMIN".equals(loginUser.getRole())) {
            logger.warn("접근 권한 없음: 관리자만 접근 가능");
            response.sendError(HttpServletResponse.SC_FORBIDDEN, "관리자 권한이 필요합니다.");
            return false;
        }

        return true;
    }
}

 

 

Interceptor를 Spring 애플리케이션에 등록하려면  WebMvcConfigurer를 구현하는 설정 클래스를 작성합니다.

package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.example.interceptor.LoginCheckInterceptor;
import com.example.interceptor.AdminCheckInterceptor;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginCheckInterceptor())
                .order(1)
                .addPathPatterns("/**")
                .excludePathPatterns("/login", "/signup", "/css/**", "/*.ico", "/error");

        registry.addInterceptor(new AdminCheckInterceptor())
                .order(2)
                .addPathPatterns("/admin/**");
    }
}

위 코드에서는 LoginCheckInterceptor와 AdminCheckInterceptor를 등록하고, 각 Interceptor의 적용 경로와 제외 경로를 설정했습니다.

특정 경로를 인터셉터 적용 대상에서 제외하려면 excludePathPatterns() 메서드를 사용할 수 있습니다.

또한, 여러 인터셉터를 등록할 수 있으며 order() 메서드를 사용하여 실행 순서를 지정할 수 있습니다.

 

 

예외처리

Interceptor에서 발생하는 예외를 처리하기 위해 @RestControllerAdvice를 사용하여 글로벌 예외 처리를 구현할 수 있습니다.

package com.example.advice;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        logger.error("예외 발생", e);
        return ResponseEntity.status(500).body("서버 오류 발생: " + e.getMessage());
    }
}

 

예외를 더 세부적으로 처리하려면 사용자 정의 예외와 그에 대한 처리기를 구현할 수 있습니다.

 

인터셉터는 SpringMVC의 HandlerAdapter 이후에 실행되며, 필터는 서블릿 컨테이너에서 관리되어 인터셉터보다 먼저 실행됩니다. 필터는 모든 요청을 처리할 수 있으며, 주로 보안, 로깅, 압축 등의 작업에 사용됩니다.

 

 

이번 글에서는 Spring Boot에서 인터셉터를 구현하고 설정하는 방법을 살펴보았습니다.

인터셉터를 사용하면 애플리케이션의 공통 기능을 효율적으로 관리하고, 코드의 중복을 줄이며,

유지보수성을 높일 수 있습니다.

 

 

 

728x90
반응형

'BE > SpringBoot' 카테고리의 다른 글

[SpringBoot] Gradle로 jar 배포하기.  (0) 2020.08.24

댓글