쌓고 쌓다
[스프링 부트] 인터셉터 인증 체크 - 33 본문
로그인하지 않은 유저가 게시글 작성을 시도하는 경우, 게시글 작성 컨트롤러를 호출하지 못하게 해보자.
먼저, 스프링 인터셉터의 흐름을 보자.
HTTP 요청 -> WAS -> 필터 -> 서블릿(디스패처 서블릿) -> 스프링 인터셉터 -> 컨트롤러
스프링 MVC의 시작점이 디스패처 서블릿이고
스프링 인터셉터 또한 스프링 MVC의 기술이기에 디스패처 서블릿 이후에 사용된다.
스프링 인터셉터를 통해 사용자의 요청을 제한할 수 있는데.
로그인 유저와 비 로그인 유저의 요청이 어떻게 처리 되는지 보자.
1. 로그인 사용자
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
2. 비 로그인 사용자
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 스프링 인터셉터 (적절한 요청이 아니라고 판단하고, 컨트롤러 호출 X)
물론 인터셉터들을 체인하여
인터셉터1 -> 인터셉터2 -> 인터셉터3로 순서를 지정하여 차례대로 호출할 수 있다.
스프링 인터셉터 사용 방법
스프링 인터셉터를 사용하려면 HandlerInterceptor 인터페이스를 통해 구현해야한다.
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
- preHandle : 컨트롤러 호출 전 호출 ( 정확히는 핸들러 어댑터 호출 전 )
- 반환 값이 true라면, 정상 진행이 되고, false라면 핸들러 어댑터도 호출하지 않고 나머지 인터셉터도 호출하지 않는다.
- 예외 발생시 postHandle을 호출하지 않는다.
- postHandle : 컨트롤러 호출 후 호출 ( 정확히는 핸들러 어댑터 호출 후 )
- afterCompletion : 뷰가 렌더링 된 이후에 호출
- afterCompletion은 예외가 발생하더라도 항상 호출되므로 예외와 무관하게 공통처리에 유용함.
- 예외를 파라미터로 받으므로 예외를 찍어볼 수 있다.
로그인 체크 스프링 인터셉터 개발
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
log.info("인증 체크 인터셉터 실행 {}", requestURI);
HttpSession session = request.getSession(false);
if(session==null||session.getAttribute(SessionConst.LOGIN_MEMBER)==null) {
log.info("미인증 사용자 요청");
response.sendRedirect("/?redirectURL="+requestURI);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("[loginCheckInterceptor] postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("[loginCheckInterceptor] afterCompletion");
}
}
게시글 작성 버튼을 눌렀을때
컨트롤러 호출전에 로그인 여부 체크만하면 됨으로 preHandle에만 로직을 작성하면 된다.
로직은 세션이 존재하는지 아닌지에 맞춰 true, false를 반환하도록 하면 된다.
인터셉터 등록
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 로그 인터셉터
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/*.ico", "/error", "/js/**");
// 인증 인터셉터 등록 (로그인 체크)
registry.addInterceptor(new LoginCheckInterceptor())
.order(2)
.addPathPatterns("/posters/FREE/write", "/posters/QUESTION/write");
}
}
WebMvcConfigurer가 제공하는 addInterceptors()로 인터셉터를 등록할 수 있다.
addPathPatterns로 모든 경로를 인증 체크하고 excludePathPatterns로 제외하는것보다
체크할 경로만 추가하는게 좋을 것 같았다.
구현 모습
작성하기 버튼 클릭시 게시글 작성 컨트롤러는 실행되지 않고 "/"으로 redirect된다.
'프로그래밍 > spring' 카테고리의 다른 글
비회원이 댓글 작성 API POST 요청시 에러 메시지 띄우기 (0) | 2023.10.14 |
---|---|
서블릿 컨테이너의 예외 처리, 오류 페이지 (0) | 2023.10.12 |
Ajax data 여러개 넣어, @RequestBody로 여러개 받기? (0) | 2023.10.04 |
Cannot handle managed/back reference 'defaultReference': back reference type ... not compatible with managed type ... (0) | 2023.10.01 |
[스프링 부트] 회원 정보(세션)로 게시글 작성 - 32 (0) | 2023.10.01 |
Comments