CORS 에러, SOP(동일 출처 정책) (STEP 24)

CORS 에러와 SOP(동일 출처 정책)

STEP 24

URI

URI(Uniform Resource Identifier)

HTTP 요청의 목표는 리소스를 가져오는 것인데 이 리소스를 식별할 수 있게 하는 것이 URI(Uniform Resource Identifier)이다. URI는 웹 서버가 리소스를 고유하게 식별할 수 있도록 하는 것이며 하위 개념으로는 URL과 URN이 있다.

URL(Uniform Resource Locator)

특정 서버의 한 리소스가 어디 있는지 알려주기 위한 규약이다.

흔히 웹 사이트 주소로 알고 있지만 URL은 웹 사이트 주소 뿐만 아니라 컴퓨터 네트워크상의 자원을 모두 나타낼 수 있다.

구조

<스키마>://<호스트>:<포트>/<경로>?<질의>#<프레그먼트>

  1. 스키마(scheme) 사용할 프로토콜을 의미한다. 웹에서는 주로 HTTP 프로토콜을 사용

  2. 호스트(Host)와 포트(Port)

  • 하나의 Host(컴퓨터)에는 여러 개의 Process(프로그램)이 각각의 Socket(소켓)을 사용하여 데이터 통신을 하고 있기 때문에, 각각의 소켓을 구분할 필요가 있다.
  • 이 때 소켓을 구분하는 역할을 하는 것이 Port(포트).
  • ex) Tomcat을 다뤄봤다면, 로컬에서 개발을 했을 때 접근하는 URL은 localhost:8080 일 것이다. 이처럼 서버에는 포트에 따라 소켓이 연결되어 있고, 포트 번호에 따라 다른 프로토콜이 사용될 수 있다.
  • HTTP 프로토콜에서 포트 번호를 명시하지 않으면, 80번 포트를 기본 값으로 사용
  • HTTPS 프로토콜에서 포트 번호를 명시하지 않으면, 443번 포트를 기본 값으로 사용
  1. 경로

호스트에서 제공하는 자원의 경로를 의미.

  1. 질의
  • = 쿼리 스트링(Query String)

URN(Uniform Resource Name)

리소스가 어디에 위치해 있든 찾을 수 있는 방식(특정 네임스페이스의 네임으로 리소스를 식별)

Same Origin Policy(SOP: 동일 출처 정책)

웹페이지에서 다른 origin으로부터의 불러오는 리소스는 안전하지 않다고 보는 보안 메커니즘 (=같은 출처에서만 리소스를 공유할 수 있다)

이 정책에 의해서 자바스크립트로 XMLHttpRequest, fetch API 등을 이용하여 다른 웹페이지에 접근할 때는 이 동일 출처 정책으로 인하여 같은 origin의 페이지에만 접근이 가능하다.

외부 서버 경로로 ajax 요청을 보내면 에러가 발생하며 요청이 실패한다. 이는 자바스크립트 엔진 표준 스펙에 Same-Origin Policy(동일 출처 정책)이라는 보안규칙이 있기 때문이다.

origin(출처)

두 URL이 같은 origin 을 갖는다는 것은 둘의 프로토콜, 포트, 호스트가 같다는 것을 의미한다.

Ex)

Scheme(protocol) Host (Port) Resource
http:// store.company.com (:80) /dir2/other.html

아래 두 URL은 같은 origin이 아니다. http:// 의 기본 포트 번호는 80라서 둘은 포트가 다르기 때문이다.

http://store.company.com/dir2/other.html

http://store.company.com:81/dir/page.html

그래서 동일 출처 정책(SOP)가 적용되는 방식으로 이렇게 다른 출처의 자원에 접근하려 하면 CORS에러가 발생한다.

그러나 여러 도메인으로 구성되는 대규모 웹 프로젝트 증가, REST API를 이용한 외부 호출이 많아지는 상황에서 SOP는 적절치 않은 정책이 되기도 하고있다. 그래서 추가적으로 CORS라는 정책이 만들어졌다.

로컬 환경에서의 CORS 에러

<!-- 📁 index.html -->
...
<script type="module" src="js/module.js"></script>
...

위 코드를 로컬 환경에서 실행하면 CORS policy에러가 발생한다.

XMLHttpRequest, fetch API을 사용해 요청한 것도 아니고, 동일경로~ 에 있는 js/module.js를 요청한 것 같은데 왜 에러가 발생할까?

  • 원인

    • <script type="module">가 포함된 HTML 파일을 로컬에서 실행할 경우 자바스크립트 모듈 보안 요구사항으로 인해 CORS 에러가 발생하기 때문이라고 한다.
    • ~경로~/index.html에서 ~경로~/js/module.js로 요청이 간 것이 아니라, ~경로~/index.html에서 null/js/module.js로 요청이 간 것이다. 결국 다른 출처를 가져서 에러가 나는 것이다. (웹에서 로컬 파일에 접근하지 못하도로 하기 위해서 이렇게 되는 것이라고 함)
  • 해결

    • 서버에 올려 프로토콜, 호스트, 포트를 같게 만들면 CORS 에러가 해결된다.

CORS

CORS란?

Cross-Origin Resource Sharing(교차 출처 자원 공유)

웹 브라우저에서 외부 도메인 서버와 통신하기 위한 방식을 표준화한 메커니즘. 서버와 클라이언트가 정해진 헤더에 따라 서로 요청이나 응답에 반응할지 결정하는 방식으로, 요청을 받은 웹서버가 허용할 경우 다른 도메인의 웹페이지 스크립트에서도 자원을 주고받을 수 있게된다.

선택적 자원에 대해 허용한 origin들만 요청할 수 있도록 하기 때문에 필요하다.

  • 보안 상의 이유로 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한한다. 즉 CORS는 서로 다른 출처(Origin)간에 resource를 전달하는 방식을 제어하는 메커니즘이다.
  • CORS 요청이 가능하려면 서버에서 특정 헤더인 Access-Control-Allow-Origin과 함께 응답해야 한다.

출처: MDN - CORS

CORS와 브라우저

origin(출처)는 브라우저가 판별한다.

CORS를 위반했을 때

  • 서버는 정상적으로 응답
  • 응답의 파기 여부는 브라우저가 결정

CORS 작동 방식

웹 어플리케이션은 자신의 origin과 다른 리소스를 요청할 때, CORS를 실행한다.

  1. 사용자의 첫 요청

    • HTTP를 사용하여 요청을 보낸다.
    • 브라우저는 요청 헤더의 Origin 필드에 요청을 보내는 origin(출처)를 함께 담아 보낸다.
  2. 서버의 응답

    • 응답 헤더

    Access-Controll-Allow-Origin을 보낸다. (리소스에 접근가능한 허용된 출처들의 정보가 담김)

    서버측에서도 CORS에 대한 처리가 당연히 필요하다.

  3. 응답을 받은 브라우저

    • 자신이 보냈던 Origin과 받은 응답의 Access-Controll-Allow-Origin을 비교하여 해당 origin에서 요청할 수 있는거라면 리소스 전송을 허용하고 불가능하다면 에러를 발생시킨다.

Preflight

웹 브라우저는 본 요청을 보내기 전에 preflight 요청(사전 요청)을 먼저 날린다. 이를 통해 실제 요청하려는 경로와 같은 URL에 대해서 옵션 메서드로 요청을 미리 날려보고 요청을 할 수 있는 권한이 있는지 확인한다.

  • HTTP의 OPTIONS 메서드가 사용된다.

  • 실제 요청

CORS에 관여하는 응답 헤더

Request headers(클라이언트의 요청 헤더)

  • Origin 요청을 보내는 페이지의 origin(출처)

  • Access-Control-Request-Method 실제 요청에서 어떤 메서드를 사용할 것인지 알리기 위함

  • Access-Control-Request-Headers 실제 요청에서 어떤 헤더를 사용할 것인지 알리기 위함

Reponse headers(클라이언트의 응답 헤더)

  • Access-Control-Allow-Origin

    *이면 모든 외부 도메인에서 모든 요청을 허용한다는 것 (Access-Control-Allow-Origin: *)

Simple Request

  • 예비 요청이 없다.

Credentialed Request

요청에 인증과 관련된 정보를 담을 수 있게 하여 CORS에서 보안을 좀 더 강화할 수 있는 방법

credential 옵션의 종류

❗ TODO

더 알아보기

Comment

웹 보안상 기본적으로 SOP 정책이 적용된다는 것을 처음 알게되었다. 그리고 CORS도 처음 접해보는 개념인데 어떤 역할을 하는지는 이해가 가나, 구체적으로 어떻게 사용하는지는 잘 모르겠다. 팀원분들 문서도 살펴보고 추가적으로 더 공부하면서 정리필요

References

팀원들 결과물

Categories:

Updated: