CORS

Seokki Oh·2022년 4월 30일
0

Cross-Origin Resource Sharing

교차 출처 리소스 공유라는 뜻을 갖고 있다
프론트엔드 개발자라면 필연적으로 마주하게 되고 경험이 없을 때에는 참 많이 당황시키는 오류 중에 하나다
이쪽도 대략적으로 알고 있기 때문에 더 공부해보고자 하는 마음을 접었었지만 요즘에 하나라도 정말 똑바로 알자 라는 개발공부 모토가 생겨서 이것도 나름 깊이 있게 공부해보게 되었다

웹은 SOP(Same Origin Policy)를 지향한다 그래서 같은 출처에서만 정보를 제공하도록 한다
velog.io에서 google.com으로 api요청을 한다면 그것이 block되는 것이 기본이라는 것이다
하지만 웹의 특성상 다른 출처에서 정보를 가져와야할 일이 늘 있다
그렇기 때문에 CORS 정책 안에서 리소스를 공유할 수 있게 한 것이다

출처란

같은 출처, 다른 출처에 대한 구분이 먼저 있어야 출처를 구분할 수 있을 것이다 먼저 주소를 예를 들고 각각의 영역이 가리키는 부분은 아래와 같다

https://www.naver.com:80/users?type=man
// https:// = protocol
// www.naver.com = host
// 80 = port
// users = path
// ?type=man = querystring

여기서 같은 출처가 되기 위한 조건은 protocol, host, port가 같아야하는 경우다

https://naver.com:80을 기준으로 할 때에

http://naver.com:80 // X, protocol가 다름
https://papago.naver.com:80 // X, host가 다름
https://naver.com:7000 // X, port가 다름

출처비교시 유일하게 포트를 무시하는 브라우저는 I.E.다
정말 징한 녀석이다

CORS 방식

기본적인 흐름은 클라이언트에서 네트워크 요청시에 header의 origin 필드에 자신의 출처를 담아서 보낸다
이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더의 Access-Control-Allow-Origin이라는 값에 “이 리소스를 접근하는 것이 허용된 출처”를 내려주고, 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해본 후 이 응답이 유효한 응답인지 아닌지를 결정한다.
이것이 CORS의 기본적인 흐름이다
하지만 CORS가 이루어지는 방식을 브라우저가 요청,응답을 하는 세 가지 시나리오로 통해서 알아볼 필요가 있다 그 세 가지를 알아야 CORS 이슈 해결을 더욱 쉽게 할 수 있을 것이다

CORS 시나리오들

1. Preflight Request

우리가 일반적으로 api 요청을 할 때 이뤄지는 방식이다
한 번에 request와 response가 이루어지는 것 같지만 사실은 2번이다
1번의 예비요청(OPTIONS 메소드) 후에 본 요청으로 데이터의 교환이 이루어진다
예비요청 때에 origin값과 Access-Control-Allow-Origin의 비교가 이루어진다
이 요청은 값이 다르더라도 요청 성공(200)이 된다

하지만 이때 브라우저는 CORS 조건이 맞지 않음을 파악하고 본 요청 때에 CORS에러를 내게 된다

2. Simple Request

이 요청은 preflight와 다르게 요청이 한 번만 이루어진다
예비 요청이 없는 것인데 이것만 다를 뿐 Preflight요청과 다르지 않다
다만 이 요청에는 몇 가지 조건이 따른다

  • 요청의 메소드는 GET, HEAD, POST 중 하나여야 한다.
  • 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만 허용된다.

보통의 api 설계에서는 만족하기 어려운 조건이다

3. Credentialed Request

기본적으로 브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest 객체나 fetch API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 함부로 요청에 담지 않는다. 이때 요청에 인증과 관련된 정보를 담을 수 있게 해주는 옵션이 바로 credentials 옵션이다
이 옵션으로는 same-origin (기본값, 같은 출처에서만 가능), include(모든 요청에 담을 수 있음), omit(모든 요청에 불가)가 있다

same-origin, include로 설정할 경우에 Access-Control-Allow-Origin 외에 조금 더 빡빡한 조건으로 요청을 검사하게 된다
그 검사 조건은 아래와 같다

  • response의 Access-Control-Allow-Origin에는 * 사용이 불가하고 명시적이어야 한다
  • 응답 헤더에는 반드시 Access-Control-Allow-Credentials: true가 존재해야한다

1편 끝

CORS의 해결방법은 2편에서 다루도록 하겠다

Reference

profile
Frontend Developer

0개의 댓글