
프로젝트에서 CORS 에러를 해결한 적이 있다.
학과생 때 진행했던 프로젝트인데 복기 과정에서 CORS에 대한 완전한 이해가 동반되지 못했다고 생각이 들어서 이번 기회에 못을 박고 넘어가자.
내 기억...

먼저 CORS란 무엇인지 짚고 넘어가자.
CORS는 Cross Origin Resource Sharing의 약자로 애플리케이션을 통합하기 위한 매커니즘이다.
여기서의 매커니즘은 한 도메인에서 로드되어 다른 도메인에 있는 리소스와 상호 작용하는 클라이언트 웹 애플리케이션에 대한 방법을 정의한다.
이때 이러한 작업은 HTTP-header를 이용해서 이루어지는데 이를 CORS라고 부른다.
솔직히 나는 이 정의가 좀 여렵다.
내가 이해한 느낌으로 재정의 해보자
CORS는 다른 오리진(cross-origin)에서 리소스를 요청할 때 보안을 위해서HTTP-header를 이용해 서버에서 믿을만한origin인지 확인하고 그에 맞는 응답을 제공하는데 이러한 매커니즘을CORS라고 한다.
cross-origin이란 다음 중 한 가지라도 다른 경우를 말한다.
답을 먼저 말하자면 꼭 필요하다.
과거에는 크로스 사이트 요청 위조(CSRF) 문제가 많이 발생했다.
Cross Site Request Forgery(CSRF)은 사용자가 인증한 세션에서 웹 애플리케이션이 정상적인 요청과 비정상적인 요청을 구분하지 못하는 점을 악용하는 공격 방식으로, 웹 애플리케이션이 사용자의 요청이 실제 사용자가 전송한 것인지 확인하지 않는 경우에 자주 발생한다.
CSRF에 대한 더 자세한 내용은 친절하게 설명해주는 이 사이트를 참고하자.
이러한 문제를 해결하기 위해서 이제는 모든 브라우저가 동일 오리진 정책을 채택한다.
말그대로 동일한 오리진에서 오는 요청만을 허락하는 정책이다.
클라이언트 URL의 프로토콜, 포트 및 호스트 이름은 모두 클라이언트에서 요청하는 서버와 일치해야 한다.
이는 다른 오리진에서의 확인되지 않은 요청을 사전에 방지하는 정책이기도 하다.
예를 들어 아래 URL의 오리진과 클라이언트 URL http://example.com/dir/page.html의 오리진을 비교해보자.
| URL | 성과 | 이유 |
|---|---|---|
| http://example.com/dir2/new.html | 동일한 오리진 | 경로만 다름 |
| http://example.com/dir/inner/other.html | 동일한 오리진 | 경로만 다름 |
| https://example.com/page.html | 다른 오리진 | 다른 프로토콜 |
| http://example.com:81/dir/page.html | 다른 오리진 | 다른 포트(http://는 기본적으로 포트 80임) |
| http://example.com/dir/page.html | 다른 오리진 | 다른 호스트 |
이러한 동일 오리진 정책은 CSRF나 특정 공격에 대하여 매우 안전하지만 같은 오리진에서만 요청이 가능하기 때문에 확장성 측면에서 유연하지 못하다.
그래서 CORS를 이용하는 것이다!!!
진행했던 프로젝트의 간단한 시스템 아키텍처는 이러하다.

보이는 것 처럼 React를 이요한 클라이언트와 Spring Boot를 이용한 백엔드 서버가 독립적으로 존재한다.
API 테스트 과정에서 클라이언트 localhost:3000과 localhost:8080은 cross-origin 상황이었다.
이는 당연하게도 클라이언트에서 백엔드 서버에 API 요청 시 CORS Error를 발생시켰다.
직접 동일 오리진 정책을 만나게된 경험
간단한 해결 방법을 채택했지만(서버 측에서 3000 포트를 승인하게하는 방법) 직접 문제를 대면하고 해결했던 좋은 경험이었다.