Postman 403오류

고동현·2024년 6월 11일
1

"더 깊이, 더 넓게"

목록 보기
4/12

간단한 오류인데 굉장히 시간이 많이 들었다.
결론부터 말하면 RestController를 Controller로 잘못적었기 때문이다.

 @GetMapping("/api/get/myComment")
    public List<CommentDto> getMyAllComment(){
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        UserEntity userEntity = userRepository.findByUsername(username);
        List<Comment> comments = commentRepository.findByUser(userEntity);
        for (Comment comment : comments) {
            System.out.println(comment.getComment());
        }
        return commentService.makeCommentDtos(comments);
    }
    public List<CommentDto> makeCommentDtos(List<Comment> comments) {
        List<CommentDto> commentDtoList = new ArrayList<>();
        for (Comment comment : comments) {
            commentDtoList.add(new CommentDto(comment.getComment()));
        }
        return commentDtoList;
    }

오류
해당 api로 요청을 보내면,

403오류가 발생한다.

403오류에 대해서 구글링을 해보면 CSRF설정이나, CORS 설정에 대한 이야기만 나온다.
왜냐하면 Authorize가 없는 상태에서 access를 하려 할때 생기는 오류가 403오류이기 때문이다.

그러나, CSRF나 CORS설정은 이미 WebConfig에서 해놓은 상태

     http
                .csrf(csrf->csrf.disable());

심지어 이건 PostMan으로 설정하는거라 해당 오류가 발생할 이유가 없는데도 이런상황,,,,

그런데 이상한점은 로그가 안남는 것이다.

중간에 실제로 comment를 못가져오나? 싶어서 comment를 출력해봤는데,

hello까지 제대로 나오는상황,

현재 그렇다면, 요청이 제대로 accept되었다는 의미이고, 또한 DB에서 comment를 가져오는것 까지도 성공을 했다는것이다.

그런데 왜 오류로그가 안남는지 당최 이해가 안되었다.

해결방법

  1. 일단 로깅레벨을 설정해줬다.
logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.web=DEBUG
logging.file.name=application.log

로깅레벨에는 Error -> Warn -> Info -> Debug -> Trace 순서로 더 자세히 로그를 찍는다.

springframework.web을 debug 레벨로하면 요청 및 응답 처리, 뷰 리졸버, 컨트롤러 매핑 등 웹과 관련된 모든 상세한 정보를 출력하게 된다.

그리고 실행로그를 보니,

해당 경로 리소스가 없다. /error get을 한다. 이런 내용이 있었다.

  1. /error
    /error... 에러라.. 이거 어디서 많이 봤던건데 스쳐지나갔다.
    해당 글을 포스트 했었는데

지금 해당 api처리하는 컨트롤러는 @Controller로 설정을 해둔 상태이다.
고로, @Controller로 설정해놓으면 기본적으로 view를 반환하려고 해당 리소스를 찾는다.

그런데 Resource가 not found인것이다.
그러면 예외가 터지는데
컨트롤러에서 예외가 발생하여서 WAS까지 전파가 된다.

  • 예외 발생 흐름
    WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)

스프링 부트에서는 ErrorPage를 자동으로 등록하고, /error를 기본 오류 페이지로 설정한다. 즉 상태코드와 예외를 따로 설정하지 않으면 모두 기본 오류 페이지로 가게된다.

고로 따로 ErrorPage를 우리는 설정하지 않았으므로, 스프링 부트가 기본으로 설정해놓은 /error로 요청을 다시 보내서 view를 보는것이다.

그리고 이 /error로 가라는 요청은 BasicErrorController라는 스프링 컨트롤러가 대신 해준다.

  • sendError() 흐름
    WAS(sendError 호출 기록 확인) <- 필터 <- 서블릿 <- 인터셉터 <- 컨틀롤러(response.sendError())

그럼 로그와 같이 get /error 요청을 다시 보내는데, 여기서 access 토큰없이 접근을 하려니까 Authorized가 나오지 않은것이다.

고로, 다시 로그로 가서 설명해보자면
클라이언트가 서버로 /api/get/myComment 요청 -> access토큰 있음 인가 -> 비즈니스 로직 처리 (로그로 comment확인) -> view가 없음 -> 컨트롤러 예외 발생

WAS에서 다시 /error 로 get 요청 보냄 -> 여기서는 access토큰이 없음 -> 인가가 안됨 -> 고로 UnAuthorized 오류 발생

여기서 이제 왜 403 오류가 생겼는지 이해했다.
내가 요청을 서버로 보낼때는 Access토큰이 있어서 괜찮았는데 와스 쪽에서 다시 /error요청을 보내니까 이때는 Access토큰이 없어서 오류가 발생한 것이다.

고로 view를 반환하는게 아닌 JSON형식을 반환하게 @RestController로 바꿔주자.

정상적으로 해결했습니다.

Controller를 RestController로 적지않은 것을 그냥 발견하기는 상당히 어렵습니다. 왜냐.. 자신이 잘못적은 코드는 자기가 파악하기 힘들기 때문,

로깅레벨을 설정해 오류를 파악하고

이를통해 예외 발생과정과 WAS의 재요청 + Access토큰을 이용한 인가까지
간단한 오류지만 복합적으로 다시 내용을 복습하게 된 좋은 경험이었습니다.

profile
항상 Why?[왜썻는지] What?[이를 통해 무엇을 얻었는지 생각하겠습니다.]

0개의 댓글