이번 글에서는 웹 개발에서 자주 마주치는 CORS(Cross-Origin Resource Sharing) 문제에 대해 이야기해보려 합니다.
근래에 리눅스에 대한 학습을 진행하고 있습니다. 마무리 단계에서 가상 머신에 호스트 머신에서 개발한 To-do list 웹 애플리케이션을 배포하는 실습을 진행했고 여러 문제에 직면하게 되었습니다.
여러 문제들 중에서 가장 많은 시간이 소요된 단계는 바로 CORS 설정 단계였습니다. 운 좋게도 동료분께서 CORS와 관련된 좋은 인사이트를 주셨고 이 글에서 그 인사이트를 기반으로 CORS가 무엇인지, CORS 문제를 단계별로 접근하는 방법에 대해서 자세히 알아보고자 합니다.
위의 문장은 제가 얻게 된 좋은 인사이트를 간략하게 요약해본 것입니다. 부끄럽지만 여러 프로젝트를 진행하며 CORS 문제를 직면하게 될 때마다 저는 백엔드, 즉 서버의 관점에서 CORS 문제를 바라봤습니다.
그 이유는 매우 간단했습니다. Spring Boot에서 CORS 설정을 진행했기 때문입니다.
서버에서 설정한다. → 서버의 관점에서 CORS를 바라본다.
네. 잘못된 생각의 흐름이었습니다. 결론부터 얘기해보자면 CORS는 브라우저와 관련된 개념입니다. 즉, 브라우저 관점에서 바라보아야 합니다.
문제 접근에 앞서, CORS가 무엇인지 정의를 내려보고 가면 좋을것 같습니다.
CORS는 브라우저가 자신의 출처가 아닌 다른 어떤 출처(도메인, 스키마 혹은 포트)로부터 자원을 로딩하는 것을 허용하도록 서버가 허가 해주는 HTTP 헤더 기반 메커니즘입니다. - MDN(CORS)
네. 어렵습니다. 주요 용어인 출처와 자원에 대해 정리해보고 좀 더 쉽게 변경해보겠습니다.
출처(Origin)는 웹 페이지나 웹 애플리케이션의 근원지를 의미합니다.
예를 들어, https://www.example.com:443
과 같은 형태입니다.
자원(리소스)은 웹 페이지, 이미지 등 웹에서 사용되는 모든 종류의 파일을 의미합니다.
이를 바탕으로 CORS를 좀 더 쉽게 정의하면 다음과 같습니다.
CORS는 웹 브라우저가 현재 접속 중인 웹사이트에서 다른 웹사이트의 내용(자원)을 안전하게 가져와 사용할 수 있도록 하는 보안 체계입니다.
CORS에 대한 정의를 내려봤으니 이제 CORS 문제가 무엇인지 정의를 내려봅시다.
CORS 문제는 다음과 같이 정의할 수 있습니다.
CORS 문제는 웹 브라우저가 보안상의 이유로 현재 웹페이지와 다른 출처의 리소스에 대한 접근을 기본적으로 차단하여 발생하는 문제입니다.
CORS가 무엇인지, CORS 문제가 무엇인지 이제 알게 되었습니다. 그럼 어떤 방식으로 접근해야 CORS 문제를 '잘' 해결할 수 있을까요? '잘'이라는 용어를 사용한 이유는 문제 해결 자체는 생각보다 쉽기 때문입니다.
예를 들어,
서버에서 모든 Origin에 대해서 허가하도록 하는 CORS 설정을 진행하면 대부분의 문제는 해결됩니다.
Nginx와 같은 웹 서버에서 CORS 헤더를 설정하고, 서버 측에서도 CORS 설정을 둘 다 진행해도 문제는 해결됩니다.
위의 해결 방법들을 적용하면 문제가 해결됩니다. 하지만 추후에 아래와 같은 문제가 발생할 가능성이 높아집니다.
1번의 경우 보안상 위험할 수 있습니다.
2번의 경우 불필요한 중복을 초래하고 관리를 복잡하게 만들 수 있습니다.
즉, 근본적인 문제 해결과는 거리가 있습니다.
그렇다면 어떻게 CORS 문제를 접근해야 근본적으로 문제를 해결할 수 있을까요? 사실 각자의 환경이 다르기 때문에 모든 문제를 근본적으로 해결하는 일반화된 해결 방법은 없다고 생각합니다.
그래서 저는 미래의 저를 위해 CORS 문제를 순차적으로 접근하는 방법을 한번 남겨보려 합니다.
CORS 문제가 발생
브라우저 개발자 도구의 콘솔에서 CORS 관련 오류 메시지 확인
클라이언트 측 요청 확인
서버 측 CORS 설정 확인
네트워크 환경 확인
서버 로그 확인
서버 CORS 설정 조정
프리플라이트 요청(Preflight Request) 확인
프록시 서버나 API 게이트웨이 사용 고려
이번 글에서는 CORS가 무엇인지, CORS 문제를 접근하는 방법 등에 대해서 알아보았습니다. 사실 이 글에서 다룬 내용은 관련된 방대한 내용 중에 일부입니다. 추후 필요성을 느낀다면 HTTP 헤더, Ngnix 리버스 프록시 등의 내용을 추가적으로 학습해보면 좋을 것 같습니다.
조금 새는 얘기지만 CORS 문제 말고도 개발 환경과 프로덕션 환경에 대한 차이로 인해 발생한 문제, Nginx 설정 관련 문제 등 여러 문제들을 직면했고 해결했습니다. 또 동료분들을 도와드리며 제 환경에서는 겪지 못한 문제를 보기도 했습니다. 여력이 생긴다면 다음 기회에 해당 내용도 남겨보도록 하겠습니다.