프로젝트를 진행 중에 Swagger API 에서 요청에 대한 응답으로 403 에러가 반환되고 있다는 것을 발견했습니다.
위 에러를 마주하였을 때 가장 먼저 의심한 것은 CORS 에러였습니다.
다만, 조금 더 고민해보니 앞뒤가 맞지 않는 추론이었습니다.
왜냐하면, Swagger의 Origin과 서버의 Origin은 동일한 Origin이기 때문입니다.
Same Origin Policy
왜 동일한 Origin인데 CORS에러가 아니라고 생각했냐 라고 묻는다면 CORS 에러가 나온 이유를 생각해보면 당연합니다.
웹 어플리케이션은 기본적으로 동일한 출처의 리소스만 공유할 수 있습니다.
다만, 동일한 출처의 리소스만 공유할 수 있으면 웹 어플리케이션을 사용하는 데 너무 번거롭기 때문에 편의성을 위해 몇몇 출처를 허용해준 것이 CORS 입니다.
즉, Swagger의 Origin과 서버의 Origin은 동일하기 때문에 CORS 에러가 발생할 수는 없다고 생각했습니다.
하지만, 호옥시 모르니깐 SpringBoot의 CorsConfigurationSource가 등록된 CorsFilter를 분석해보았습니다.
CORS ConfigurationSource
CorsConfigurationSource와 CorsFilter를 분석하다보니 의문점이 생겼습니다.
당연히 CorsFilter는 자기 자신의 도메인을 안다고 생각했는데 소스를 분석하다보니 CorsConfigurationSource를 설정할 경우 CorsConfigurationSource에 정의된 Origin만 허용해주고 있었습니다.
그리고, 정의된 Origin이 아닐 경우에는 403 Forbidden 에러를 반환하고 있었습니다.
그래서, CorsConfigurationSource에 제 서버의 도메인을 추가시켜줬습니다.
그리고, Swagger를 사용해보니 정상적으로 동작하는 것을 확인할 수 있었습니다.
일단, 해결이 됬는데 굉장히 찝찝하다..🥲
네, 굉장히 찝찝했습니다.
동일 출처인 것을 서버에 명시를 하는 게 맞는 건가?
Native Android Application은 CORS 설정을 하지 않아도 된다고 했는데 왜지?
...
그래서, 제가 CORS에 대해서 올바르게 알고있는 지 확인하기 위해 다시 한번 공부를 해보았습니다.
CORS Error 발생시키는 것은 브라우저다.
CORS에 대해서 공부하며 알지 못 했던 것을 발견했습니다.
바로, CORS Error를 발생시키는 주체는 브라우저라는 것입니다.
사실 기존에는 서버에 CORS 설정을 해주면 CORS 문제가 해결되었기 때문에 아 서버가 CORS Error를 발생시키는 주체구나 라고 당연하게 생각해왔습니다.
그러나 CORS의 Prefilght 메커니즘을 자세히 살펴보니, 브라우저가 서버에서 응답한 헤더들을 사용해 조건에 맞지 않으면 CORS Error를 발생하는 것이었습니다.
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
CORS ConfigurationSource를 설정해줄 필요가 있을까?
그렇습니다. 출처 구분은 서버가 하는 것이 아니라 브라우저가 서버의 응답 헤더를 받고 브라우저에서 발생시키는 것입니다.
그렇다면, Native Android 에서는 CORS Error를 발생시킬까요?
아닙니다. 발생시키지 않습니다.
그렇다면, CORS ConfigurationSource를 설정해줄 필요가 있을까요?
Android에서는 CORS Error를 발생시키지 않고, Swagger는 서버와 동일 출처이기 때문에 굳이 추가로 Origin을 추가해줄 필요가 없다고 판단했습니다.
그래서, CorsConfigurationSource를 제거하고 테스트를 해보았더니..
Android에서 요청 응답 정상, Swagger에서 요청 응답 정상으로 모두 정상적으로 작동했습니다.
응답 헤더 또한 확인해보니 아래와 같이 X-Frame-Options에 SAMEORIGIN이라고 왔습니다.
결론
애초에 Android Native Application이기 때문에 CORS 설정을 할 필요가 없었습니다...🥲
나중에 기억한 사실이지만 전에 AOS 개발자분들이 캡스톤 디자인을 할 때 해당 서버를 이용했는데 이때 Android만 사용한 것이 아니라 웹도 사용을 해서 제가 CORSConfiguration을 추가해주고 캡스톤이 끝나고 제거하지 않았던 것입니다.
덕분에 CORS에 대해서 깊게 알 수 있는 기회였습니다. 감사합니다😀
'Project Trouble Shooting > [EATceed] 몸무게 증량 어플' 카테고리의 다른 글
Cipher 클래스에서 암호화·복호화 지연 이슈 해결 (0) | 2024.09.25 |
---|---|
예외가 발생해도 이벤트 발행 후 처리하기 (0) | 2024.09.11 |
DDD의 Entity와 JPA의 Entity를 구분해야하는 것인가? (0) | 2024.08.15 |
헥사고날 아키텍처 회고 (2) (0) | 2024.07.28 |
ApplicationContext Caching을 활용한 테스트 환경 개선 (2) | 2024.07.23 |