ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 잘못된 URI 접근 시, 커스텀 에러 페이지로 이동
    스터디 2018. 9. 4. 19:41

    이번 포스팅은 사용자가 잘못된 URI를 입력했을 때, 커스텀 에러 페이지로 가게 하는 방법에 대해 알아보겠습니다.


    아래는 프로젝트 진행시 요구사항이었습니다. 주목해서 볼 부분은 세 번째 항목인 스프링 시큐리티를 사용하지 못하도록 한 부분입니다. 



    스프링 시큐리티를 사용하지 않고, 잘못된 URI 입력했을 때 커스텀 에러 페이지로 가게 하는 가장 쉬운 방법은 인터셉터에서 요청 URI를 검사하여 허용하지 않은 URI일 경우 에러 페이지로 리다이렉트해주는 것입니다.


    그래서 아래와 같이, 허용된 URI를 직접 관리해서 이것 이외의 URI가 요청될 경우 에러페이지로 리다이렉트 하는 식으로 구현했습니다. 


    하지만 이러한 방법에는 몇가지 문제가 있다고 생각했습니다. 


    첫 번째로, URI가 새로 추가 될 때마다, 매번 URI를 등록해 주어야한다는 것과

    두 번째로, 개발자의 실수로 URI를 허용해 주지 않는다면 에러 페이지가 보여진다는 점이었습니다.


    @Slf4j
    public class CheckUriInterceptor extends HandlerInterceptorAdapter {
    private static final String[] allowedUris = new String[] {"/api/reviews", "/closet", "/static"};

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
    String uriPath = request.getServletPath();

    for (String uris : allowedUris) {
    if(uris.startsWith(uriPath) || uris.equalsIgnoreCase("/")) {
    log.info("uri path : {}, pass success", uriPath);
    return true;
    }
    }
    response.sendRedirect("/errors/404");
    return false;
    }
    }


    @Controller
    @RequestMapping("/errors")
    public class ErrorController {

    @GetMapping("/400")
    public String error400Page() {
    return "/error/error400";
    }

    @GetMapping("/404")
    public String error404Page() {
    return "/error/error404";
    }

    @GetMapping("/500")
    public String error500Page() {
    return "/error/error500";
    }
    }


    그래서, 이러한 수고로움을 덜어줄 수 있는 방법이 없을까 고민해서 찾은 방법이 스프링에서 제공하는 ErrorController 인터페이스를 이용하는 것이었습니다.

    이를 통해 HTTP 상태 코드 별로 커스텀 에러 페이지를 다양하게 보여줄 수 있었습니다.


    Custom Error Page

    스프링 부트에서는 기본적으로 whitelabel.enabled 옵션이 true로 되어있어서, 에러 발생 시 whitelabel 에러 페이지를 보여주게 됩니다.

    에러가 발생했을 때 whitelabel 에러 페이지를 더이상 나타나지 않도록 하기위해 application.yml 에 가서 아래와 같이 false로 변경해주었습니다. 

    server:
    error:
    whitelabel:
    enabled: false


    또한, application.yml 파일에 아래와 같은 설정을 해주지 않았다면, 에러가 발생했을 때 스프링은 알아서 /error로 redirect 시켜주게 됩니다. 리다이렉트 경로를 바꾸고 싶다면 아래와 같이 변경할 수 있습니다. 

    server:
    error:
    path: /errors


    Custom Error Controller 설정

    이제 위에서 설정한 경로에 맞게 컨트롤러를 작성만 해주면 됩니다. 단, ErrorController 인터페이스를 구현한 컨트롤러여야만 합니다.

    ※ 공식 문서에는 아래 보이는 getErrorPath( ) 메소드를 에러가 발생했을 때 호출할 에러 페이지 경로 라고 적고 있습니다. (하지만, 경로를 적지 않아도 정상적으로 돌아갑니다;;)

    @Controller
    @RequestMapping("/errors")
    public class CustomErrorController implements ErrorController {

    @GetMapping
    public String error400Page() {
    return "/error/error400";
    }

    ...


    @Override
    public String getErrorPath() {
    return "/errors";
    }
    }


    Http 상태 코드 별로 커스텀 에러페이지

    프로젝트를 진행하며 Http 상태 코드 별로 에러페이지를 각기 다르게 보여주고 싶었습니다. 이를 위해 상태 코드별로 아래와 같이 분기처리를 진행하였습니다. 

    @Controller
    @RequestMapping("/errors")
    public class CustomErrorController implements ErrorController {

    @GetMapping
    public String handleError(HttpServletRequest request) {
    Optional<Object> maybeStatus =
    Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE));
    if(maybeStatus.isPresent()) {
    Integer statusCode = Integer.valueOf(maybeStatus.get().toString());
    if(statusCode == HttpStatus.NOT_FOUND.value())
    return "/error/error404";


    ...


    }
    return "/error";
    }

    @Override
    public String getErrorPath() {
    return "/errors";
    }
    }



    참고

    https://www.baeldung.com/spring-boot-custom-error-page

    https://blog.naver.com/songintae92/221351505091

    '스터디' 카테고리의 다른 글

    XSS 공격에 대한 방어  (0) 2018.09.04

    댓글

Designed by Tistory.