CORS(교차 출처 리소스 공유)

daybyday·2021년 1월 25일
0

Web

목록 보기
3/5

CORS (Cross-Origin Resource Sharing)

추가 HTTP 헤더를 사용하여 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제

즉, CORS란 도메인/포트가 다른 서버의 자원을 요청하는 매커니즘이다.

만약 https://domain-a.com에서 XMLHttpRequesthttps://domain-b.com/data.json이라는 자원을 요청한다면 브라우저는 보안 상의 이유로 교차 출처 HTTP 요청을 제한한다.

XMLHttpRequestFetch APISOP(Same-Origin Policy, 동일 출처 정책), 같은 출처에 있는 자원만 공유할 수 있다는 규칙을 따른다.

그러나 같은 출처의 자원을 사용하지 않는 경우가 굉장히 많기 때문에, CORS 정책을 지킨다면 출처가 다르다고 해도 자원 공유를 허용한다.

따라서 다른 출처의 자원을 불러오려면 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.

위 그림에서 파란색 박스의 Image는 domain-a.com의 자원이므로 SOP을 만족해 언제든 자원을 공유할 수 있다.

하지만 빨간색 박스의 Canvas w/ image는 domain-a.com과 다른 domain-b.com의 자원을 불러오려고 하고 있으므로, CORS의 제한을 받는다.


CORS를 사용하는 요청

  • XMLHttpRequest, Fetch API
  • 웹폰트 (CSS 내 @font-face에서 교차 도메인 폰트 사용 시)
  • WebGL 텍스쳐
  • drawImage()를 사용해 캔버스에 그린 이미지/비디오 프레임
  • 이미지로부터 추출하는 CSS Shapes

CORS 동작 과정

  1. 웹 어플리케이션이 요청을 보냄

    • 요청 헤더에 Origin을 담아 보냄
  2. 서버가 요청에 응답함

    • 응답 시 헤더의 Access-Control-Allow-Origin에 '이 리소스에 접근 가능한 출처'를 보내줌
  3. 브라우저가 응답을 받음

    • 브라우저는 자신이 요청한 Origin과 응답으로 받은 Access-Control-Allow-Origin이 같은지 비교 후 다르다면 CORS 오류를 일으킨다.

이 때 출처는 비교하는 로직은 브라우저에 구현되어 있다. 서버는 CORS를 위반하더라도 정상적으로 응답을 보내준다. 브라우저가 출처를 비교하여 CORS 정책을 위반하였다고 판단되면 응답을 버리는 것이다.

따라서, 브라우저를 통하지 않고 서버 간 통신을 할 때는 이 정책이 적용되지 않는다.


CORS 동작 과정 시나리오


  1. Simple request(단순 요청)
    • 예비요청(preflight)를 보내지 않음
    • 단순 요청을 사용할 수 있는 경우
      • 요청의 메소드가 GET,POST,HEAD 중 하나여야 함
      • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하지 말아야함
      • 만약 Content-Type를 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용된다.
    • 조건이 까다로워 거의 해당되는 경우가 없음.


  1. Preflight
    • 예비 요청(preflight)과 본 요청을 나누어 서버로 전송
    • 브라우저에세 리소스를 받아오라는 명령을 내리면, 브라우저는 서버에 예비 요청을 먼저 보내고 서버는 자신들의 허용 정책에 대한 정보를 담아 보내줌
    • 브라우저는 자신이 보낸 예비 요청과 서버가 보내준 허용 정책을 비교한 뒤 안전하다고 판단되면 다시 본 요청을 보내게 됨


  1. Credential request
    • 좀 더 보안을 강화하고 싶을 때 사용
    • 인증된 요청을 사용
    • Credentials 옵션에 쿠키 정보나 인증에 관련된 정보를 담아 보냄

CORS 에러를 해결할 수 있는 방법


Access-Control-Allow-Origin 설정하기

서버에서 Access-Control-Allow-Origin 헤더에 알맞을 값을 세팅해주면 문제는 해결된다. 하지만 문제는 그걸 내가 설정할 수는 없다는 점이다...


Webpack Dev Server 프록시 설정하기

저번에 react 토이 프로젝트를 개발할 때 CORS 에러를 마주친 적이 있는데 이 방법으로 해결했었다.

TIL | CORS 에러 해결 / map() 메소드

로컬 환경에서 개발할 때 package.json에 가서 다음과 같이 프록시를 설정해주면 해당 서버의 자원을 사용할 수 있다.

포트번호까지만 넣어주고, API 요청할 때는 proxy에 써준 부분을 제외하고 뒷 부분만 url로 넣어주면 된다.

참조

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://evan-moon.github.io/2020/05/21/about-cors/

0개의 댓글