개발 상식

[WEB] CORS와 SOP의 개념 및 CORS 에러 해결방법

킹우현 2023. 8. 18. 21:34

들어가기 전에 알아두어야 할 용어

1) 출처(Origin)

우리가 어떤 사이트를 접속할때 인터넷 주소창에 우리는 URL이라는 문자열을 통해 접근하게 된다.

 

이처럼 URL은 https://domain.com:3000/user?query=name&page=1 과 같이 하나의 문자열 같지만, 사실은 위와 같이 여러개의 구성 요소로 이루어져 있다.

  • Protocol(Scheme) : http, https
  • Host : 사이트 도메인
  • Port : 포트 번호
  • Path : 사이트 내부 경로
  • Query string : 요청의 key와 value값
  • Fragment : 해시 태그

여기서 출처(Origin)란 ? Protocol + Host + Port

 

👉🏻 즉, 출처(Origin) 라는 것은 Protocol 과 Host 그리고 Port 까지 모두 합친 URL로, 서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐놓은 것을 의미한다고 보면 된다. (ex. https://localhost:3000)

 

출처(Origin)의 동일함은 두 URL의 구성 요소 중 Protocol(Scheme), Host, Port 이 3가지만 동일하다면 동일 출처로 판단한다.

 

2) SOP(Same-Origin Policy)

먼저 SOP(Same Origin Policy) 정책은 단어 그대로 동일한 출처에 대한 정책을 말한다. 그리고 이 SOP 정책은 '동일한 출처간에만 리소스를 공유할 수 있다.'라는 법률을 가지고 있다.

 

즉, 동일 출처(Same-Origin) 서버에 있는 리소스는 자유로이 가져올수 있지만, 다른 출처(Cross-Origin) 서버에 있는 리소스는 상호작용이 불가능하다는 뜻이다.

 

Q. 동일 출처가 아닌 경우 접근을 차단하는 이유는 뭘까?

사실 출처가 다른 두 어플리케이션이 자유로이 소통할 수 있는 환경은 꽤 위험한 환경이다. 만일 제약이 없다면, 해커가 CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting) 등의 방법을 이용해서 우리가 만든 어플리케이션에서 해커가 심어놓은 코드가 실행하여 개인정보를 가로챌 수 있다.

 

다음은 SOP 정책이 없는 상황에서 악의적인 홈페이지에 접속하는 상황을 가정 한 것이다.

 

SOP 정책이 없는 상황에서 악의적인 홈페이지에 접속하는 상황

  1. 사용자가 악성 사이트에 접속한다.
  2. 이때 해커가 몰래 심어놓은 악의적인 JS가 실행되어, 사용자가 모르는 사이에 어느 포털 사이트에 요청을 보낸다.
  3. 그럼 포털 사이트에서 해당 브라우저의 쿠키를 이용하여 로그인을 하거나 등 상호작용에 따른 개인 정보를 응답 값을 받은뒤, 사이트에서 해커 서버(hacker.example.com)로 재차 보낸다.
  4. 이외에도 사용자가 접속중인 내부망의 아이피와 포트를 가져오거나, 해커가 사용자 브라우저를 프록시처럼 악용할 수도 있다. 

따라서 이러한 악의적인 경우를 방지하기 위해, SOP 정책으로 동일하지 않는 다른 출처의 스크립트가 실행되지 않도록 브라우저에서 사전에 방지하는 것이다.

 

CORS(Cross-Origin-Resource-Sharing)

CORS는 함축 단어로써 이를 풀면 Cross-Origin Resource Sharing 이라는 단어로 이루어져 있다.

 

이 문장을 직역하면 교차 출처 자원 공유 정책이라고 해석할 수 있는데, 여기서 교차 출처라고 하는 것은 (엇갈린) 다른 출처를 의미하는 것으로 보면 된다.

 

CORS는 쉽게 말해 다른 출처를 가진 자원을 공유하기 위한 허용/비허용 정책이다. 우리가 겪는 CORS 이슈는 이 정책을 위반했기 때문에 발생하는 것이며, 겪는 입장에서는 귀찮지만 사실 CORS는 우리가 다른 출처들로부터 가져오는 리소스가 안전하다는 최소한의 보장을 해주는 방어막인 셈이다.

 

CORS의 동작 방식

출처를 비교하는 로직은 서버에 구현된 스펙이 아닌 브라우저에 구현된 스펙이다. 응답 데이터는 멀쩡하지만 브라우저 단에서 받을수 없도록 차단을 한 것이다.

 

하지만 인터넷은 여러 사람들에게 오픈된 환경이고, 이런 환경에서 웹페이지에서 다른 출처에 있는 리소스를 가져와 사용하는 일은 매우 흔한 일이라 무턱대고 막을 수는 없는 일이다.

 

그래서 몇 가지 예외 조항을 두고 다른 출처의 리소스 요청이라도 이 조항에 해당할 경우에는 허용하기로 했는데, 그 중 하나가 바로 CORS 정책을 지킨 리소스 요청이다.

 

요약하자면 SOP 정책을 위반해도 CORS 정책에 따르면 다른 출처의 리소스라도 허용한다는 뜻이다.

 

CORS 해결 방법

CORS는 브라우저에 관련된 정책이기 때문에, 클라이언트에서 외부 API 서버로 바로 요청을 보내면 CORS 문제가 발생한다. 🚨

 

즉, 서버간에 리소스를 공유할 때는 CORS 정책을 위반하지 않고 정상적으로 응답을 받을 수 있다. 🌟

 

그러므로 이 문제를 해결하는 방식은 다음과 같다.

  • 💻 내부 api 서버로의 접근에서 CORS 문제가 발생했을 경우 ) 해당 api 서버에서 Access-Control-Allow-Origin 헤더에 내 출처를 명시한다.
  • 📲 외부 api 서버로의 접근에서 CORS 문제가 발생했을 경우 )
    • 1. 브라우저를 통하지 않고(클라이언트에서 외부 서버로 바로 요청을 하지 않고) 프록시 서버를 통해 외부 서버로 리소스를 요청한다.
    • 2. 프록시 기능을 제공하는 라이브러리를 통해 우회한다. (ex. http-proxy-middleware)
    • 3. 웹 브라우저 실행 옵션이나 플러그인을 통해 동일 출처 정책(SOP)을 회피한다.
✨프록시(Proxy)란 ? 클라이언트가 다른 네트워크에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램
즉, 클라이언트와 서버 사이의 중계 대리점 역할을 하는 것을 뜻한다.

 

단, 프론트에서는 주로 로컬 환경에 대한 CORS 문제 해결만 가능하고 배포 후에 발생하는 CORS 문제들은 서버 단에서 설정해줘야 한다고 볼 수 있다.

 

참고 : 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

https://coding-maggot.tistory.com/100#-%ED%--%B-%EB%-D%BC%EC%-D%B-%EC%--%B-%ED%-A%B-%-F%ED%--%--%EB%A-%A-%ED%-A%B--%--%EA%B-%-C%EB%B-%-C%--%EB%-B%A-%EA%B-%--%---%--%EB%A-%-C%EC%BB%AC%--%ED%--%--%EA%B-%BD%EC%--%--%EC%--%-C%EC%-D%--%--CORS%--%EB%AC%B-%EC%A-%-C%--%ED%--%B-%EA%B-%B-