스프링 & 리액트 프로젝트를 진행하면서 클라이언트에서 처음 서버로 api 통신을 할 때 마주쳤던 CORS(Cross-Origin-Resource-Sharing) 이다. 당시에는 CORS가 그저 허락한 리소스에 대해서만 통신을 할 수 있게 해주는 것이라고만 가볍게 알고 해결 법은 구글링해서 middleware 를 사용해서 통신이 가능하게 해줬다. 하지만 이런 얕게 알고 있던 지식 때문에 Access-Control-Allow-Origin 의 설정을 서버에서 * 로 해두어서 사실 상 모든 리소스에서 접근 권한이 가능하도록 설정을 했었다.
그럼 이 CORS가 무엇인지 왜 생겼는지 하나 하나 살펴보자.
SOP(Same-Origin Policy)
CORS를 얘기하다가 갑자기 이상한 SOP가 나왔다. CORS를 이해하기 위해서는 SOP에 대한 이해가 먼저 필요하기 때문이다.
먼저 SOP는 이름 그대로 동일 출처 정책 이라는 의미를 가지고 있다.
우선 Origin이 무엇인지 먼저 살펴보자.
출처(Origin)
여기서 말하는 Origin이란 우리가 사이트에 접속할 때 인터넷 주소창에 쓰는 URL중 몇 가지 요소를 의미한다.
URL은 다음과 같이 여러가지 구성요소로 이루어져있다.

- Protocol(Scheme) : http, https, ftp, smtp 등등
- Host : 사이트 도메인
- Port : 포트 번호
- Path : 내부경로
- Query String : request Parameter 요청 key, value
- Fragment : 클라이언트 북마크
이렇게 여러가지로 구성되어 있다. 이거 말고도 생략된 username, password 등도 있는데, 거의 사용되지 않아 생략했다.
그럼 저거를 다 외워야하는가. 외우면 물론 좋지만 지금 Origin을 이해하기에는 적합하지 않다.
Origin에서는 위에서 3가지만 기억하면 된다.
- Origin = Scheme + Host + port
출처(Origin)은 위에 3개로 구분을 한다. 실제로 자바스크립트로 현재 사용하고 있는 사이트의 origin을 알아낼 수 있다.
console.log(location.origin);

Origin 구분
위에서 Origin은 Scheme + Host + Port 로 구성이 된다고 했다. 이를 구분하는 좋은 자료가 있어서 가지고 왔다. 먼저 예시 도메인은 https://www.domain.com:3000 에 대한 예시이다.

동일 출처 정책(SOP)
이제 Origin이 무엇인지 알았다. 이제 동일 출처 정책이 무슨 말을 하는지 이해하기 쉬울 것이다.
동일 출처 정책은 말 그대로, 동일한 출처에 대한 정책을 의미한다. 그리고 이 정책은 다음과 같다.
동일한 출처에서만 리소스를 공유할 수 있다.
이러한 이유 때문에 서버에 있는 리소스는 자유롭게 가져올 수 있지만, 다른 서버에 있는 이미지 혹은 비디오 등은 가져 올 수 없다.
하지만 요즘 같은 시대에는 다른 서버에 있는 이미지 혹은 비디오들도 가져 올 수 있어야 한다.
대체 이런 정책이 왜 만들어진 것 일까?
동일 출처 정책이 필요한 이유
동일 출처 정책이 생긴 이유는 결국 보안상의 이유이다. 좋은 목적으로 다른 서버에 있는 리소스를 가져오는 것이라면 문제가 없겠지만 항상 개발을 할 때에는 숨겨진 이면이 있다. 누군가는 이 취약점을 이용해서 나쁜 목적으로 사용하기 때문이다.
대표적으로 CSRF 혹은 XSS 등이 있고 이 점을 이용해서 크래커는 타인의 개인 정보를 획득할 수 있게 된다. 이러한 이유때문에 SOP가 생기게 된 것이다. 하지만 우리는 결국 다른 출처에서 리소스를 불러와야 될 상황이 필요한데, 어떻게 하라는 것이냐
CORS(Cross-Origin Resource Sharing)
사실 우리를 괴롭혔던 CORS는 SOP를 해결하기 위한 해결책이다. 단어 그대로 다른 출처의 리소스 공유. 라고 쓰여져 있는게 보이는가.
SOP가 다른 출처의 리소스를 사용하는 것을 막아두니 웹 개발에 대한 제한 사항이 너무 많아졌다. 그래서 CORS를 만들어서, CORS 정책에 위배되지 않는 이상 다른 출처의 리소스를 사용하도록 한 것이다.
즉, 이제는 다음과 같이 이해를 해야한다. SOP 정책을 위반하더라도 CORS 정책을 따르기만 하면 다른 출처의 리소스는 허용한다. 이런 생각이 들 수 있다. 도대체 어떤 원리로 위의 취약점 문제들을 해결하면서 SOP 정책을 회피 할 수 있었을까?
이어서 CORS 동작 과정을 살펴보자.
CORS 기본 동작 과정
1. 클라이언트에서 HTTP 요청 헤더에 Origin을 담아서 전달
- HTTP 프로토콜을 이용해 서버에 Request 메시지를 보낸다. 이때, 여러가지 헤더도 보내지만 Origin 필드에 출처를 포함하여 보낸다.

2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아서 클라이언트로 전달
- 서버가 응답을 할 때 Access-Control-Allow-Origin 필드를 추가하고 값으로 해당 리소스에 접근하는 것이 허용된 출처 url을 같이 보낸다.

3. 클라이언트에서 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교
- 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해본 후 차단할지 말지 결정한다.
- 만약 유효하지 않다면 그 응답을 사용하지 않고 CORS 에러를 띄운다.
- 유효하다면 다른 출처의 리소스를 문제없이 가져올 수 있다.
결론적으로 CORS 정책을 따르기 위해서는 결국 서버쪽에서 Access-Control-Allow-Origin 헤더에 허용가능한 리소스 주소를 추가해주어야 CORS 문제를 해결 할 수 있었던 것이다.
참고로 브라우저의 개발자 도구에서 origin 을 조작하는 것으로 가능한지 다른 글에서 실험을 하는 것을 봤는데, 브라우저에서 이를 감지하여 차단하기 때문에 불가능하다고 한다.
여기까지가 기본적인 CORS 작동 방식이다. 이 외에 CORS 작동 방식에는 크게 3가지 시나리오가 있다.
쿠키나 토큰과 같은 인증 데이터를 다른 출처의 서버에 요청을 해야한다면 이 섹션의 지식은 필수라고 한다. 따라서 다음 포스팅에서 자세히 다뤄보도록 하겠다.
참고
1. https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F
2. https://evan-moon.github.io/2020/05/21/about-cors/
'Computer Science > Network' 카테고리의 다른 글
웹 서버와 WAS의 차이, 그리고 아파치와 NGINX 알아보기 (1) | 2023.05.12 |
---|---|
CORS 작동 방식 시나리오와 해결법 (0) | 2023.05.10 |