서론
우선 JAVA SPRING BOOT로 백엔드 서버를 개발하고 있는 상황이었다.
내부 논의를 통해 API 문서화 방식은 대중적으로 많이 사용되고 연동하기 가장 간단한 Swagger를 사용하는 것으로 진행하였다.
이때 해당 Swagger를 띄워주기 위해서 springdoc이라는 라이브러리를 사용하였고, 로컬 서버에서 별 문제없이 잘 개발하였고 prod에도 처음에는 별도의 문제가 없이 FE팀에게 전달하여 서로 잘 사용 중에 있었다.
다만 어느정도 개발을 한 이후에 BE팀에서의 JWT verify를 위하여 Spring Security를 구축하였고 로컬에서 별 문제없이 연동되어 prod로 배포하였다.
그 이후 FE팀에서도 직접 API 호출하던 것도 정상작동하여 페이지가 잘 렌더링 되었으며 잘 처리되어서 기뻤다.
다만...
문제의 시작은 다음과 같다.
GET 요청에서는 아무 문제없이 잘 반환해주던 API들이 POST, PUT, PATCH, DELETE 메서드에서만 위와 같이 403 에러를 반환하였다.
왜? 로컬에선 잘 되는데? FE prod 페이지에서도 잘 호출하는데? postman에서도 잘 되는데????
로컬에서도 잘 되고, postman으로 prod api 호출할 때도 잘 되고, FE에서도 prod api 호출하여 정상 작동 하는데...
오직 prod Swagger 환경에서만 발생하여 벌써부터 디버깅할 생각에 머리가 아찔해졌다.
경험상 spring security에서는 별도의 처리가 없으면 /error로 반환해주는데 이떄 /error로의 접근을 허용하지 않아서 403이 반환되겠구나~
바로 추가해보고 배포하여 해당 리턴값을 살펴보기로 했다.
하지만.... 어림도 없이 또다시 403이 등장하였다.
트러블 슈팅
분명 나만 이런게 아니겠지...? 다른 사람들도 똑같겠지...??
바로 구글링을 해보았다.
Stackoverflow도 많이 봤고 Github issue로도 많이 봤는데 대부분 swagger로의 접근 또한 Spring security가 막고 있어서 헤더에 토큰이 없어도 접근을 허용하는 엔드포인트 리스트에 /swagger-ui/** 로 접근을 허용하면 모두 다 해결했다는 말이 나왔었다.
(그치만 난 이미 추가했는걸...?)
딱 하나 우리의 상황과 동일한 깃헙 이슈가 있었다.
여기서는 분명 해결의 실마리를 찾을 수 있겠지?
어라...?
마법의 GPT
도저히 구글링으론 해결할 수 없어서 이 문제를 마법의 GPT 선생님께 여쭤보기로 하였다.
위와 같이 설명해주었는데 우선 차근차근 살펴보았다.
1. CORS
-> 이미 cors 설정은 다 추가했어서 만약 cors에 문제가 있었다면 FE 웹페이지에서도 우리 API를 호출 못한다. 따라서 문제 없다고 판단
2. Swagger 설정
-> 모두 별도의 인증없이 Swagger 문서로 접근하는 엔드포인트는 모두 허용 처리 해두었다.
3. CSRF도 비활성화
4. Swagger 상 표기되는 curl 요청도 직접 터미널로 날려보면 정상 반환
5. 네트워크 탭 상에서의 헤더 값을 보면 정상적으로 토큰을 담고 있다.
security쪽에서 DEBUG로 level을 수정하여 한번 prod 배포한 후 서버 로그를 확인하기로 하였다.
다만 DEBUG에서는 별다른 정보를 얻지 못해서 TRACE로 수정해보았다.
PUT 요청을 날려보니...귀신같이 CorsFilter 이후로 로그가 뚝 끊겼다.
어라...?
cors origin을 살펴보니 FE쪽 도메인만 연결해두고 정작 우리 서브도메인을 추가를 안해두었다...
부랴부랴 추가하고 다시 호출을 해보니
바로 201 호출...!
사실 이번 트러블 슈팅 과정에서도 분명 아주 사소한 무언가때문에 분명 이 문제가 발생했었을테고 내가 분명 실수를 한거겠지? 라고 생각을 했는데....그게 맞았다 ㅎㅎ...
결론
항상 내 코드를 의심하자. 라이브러리나 프레임워크는 잘못이 없다.