반응형
인터셉터를 이용해 /s가 붙은 주소의 요청을 받으면 인증 체크를 손쉽게 했었다.
// CustomApiException
package site.metacoding.everytimeclone.handler.ex;
public class CustomApiException extends RuntimeException {
public CustomApiException(String message) {
super(message);
}
}
// CustomException
package site.metacoding.everytimeclone.handler.ex;
public class CustomException extends RuntimeException {
public CustomException(String message) {
super(message);
}
}
// GlobalExceptionHandler
package site.metacoding.everytimeclone.handler;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import site.metacoding.everytimeclone.handler.ex.CustomApiException;
import site.metacoding.everytimeclone.handler.ex.CustomException;
import site.metacoding.everytimeclone.util.Script;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CustomApiException.class)
public ResponseEntity<?> apiException(Exception e) { // fetch 요청시 발동
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(CustomException.class)
public String htmlException(Exception e) { // 일반적인 요청 Get(a태그), Post(form태그) 요청
return Script.back(e.getMessage());
}
}
/s가 붙은 주소 요청이 들어왔을 때 SessionInterceptor에서 RuntimeException 오류를 터뜨렸었는데
세션이 존재하지 않는 유저가 들어오면 로그인 페이지를 리턴해주고 싶다.
GlobalExceptionHandler에서 페이지 리턴을 처리할 핸들러를 하나 더 만들어주면 된다.
// CustomPageException
package site.metacoding.everytimeclone.handler.ex;
public class CustomPageException extends RuntimeException {
public CustomPageException(String message) {
super(message);
}
}
CustomPageException을 처리하는 핸들러를 만드려고 보니
이 Global 핸들러는 @RestControllerAdvice라서 페이지를 리턴해줄 수 없다.
@ControllerAdvice로 변경해준 뒤 CustomException 핸들러에만
데이터를 리턴해줄 수 있게 @ResponseBody를 붙여주자.
ResponseEntity를 리턴하는 CustomApiException은
ResponseEntity가 @ResponseBody를 붙이지 않아도 알아서 데이터를 리턴해주기 때문에 그냥 놔둬도 된다.
package site.metacoding.everytimeclone.handler;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import site.metacoding.everytimeclone.handler.ex.CustomApiException;
import site.metacoding.everytimeclone.handler.ex.CustomException;
import site.metacoding.everytimeclone.handler.ex.CustomPageException;
import site.metacoding.everytimeclone.util.Script;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CustomApiException.class)
public ResponseEntity<?> apiException(Exception e) { // fetch 요청시 발동
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(CustomException.class)
public @ResponseBody String htmlException(Exception e) { // 일반적인 요청 Get(a태그), Post(form태그) 요청
return Script.back(e.getMessage());
}
@ExceptionHandler(CustomPageException.class)
public String htmlPageException(Exception e) { // 세션이 없을 때 htmlPageException 터뜨리기
return "redirect:/user/login-form";
}
}
이제 세션 인터셉터에서 CustomPageException을 터뜨려주면
인증이 필요한 페이지에 로그인을 하지 않은 유저가 들어왔을 때
로그인 페이지를 리턴해줄 것이다.
package site.metacoding.everytimeclone.config.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import site.metacoding.everytimeclone.domain.user.User;
import site.metacoding.everytimeclone.handler.ex.CustomPageException;
public class SessionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
User principal = (User) session.getAttribute("principal");
if (principal == null) {
throw new CustomPageException("인증에 실패하였습니다.");
} else {
return true;
}
}
}
반응형