https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
Cross Origin Resource Sharing 교차출처 방식 자원 교환
한 사이트에서 주소가 다른 사이트로 보낼 때 자주 접하는 오류 cors 오류
주소가 "어쩌구" 닷컴인 웹사이트에서 URL이 "저쩌구" 닷컴인 서비스에서
API로 정보를 받아오기 위해 "프론트에서" HTTP요청을 보냈을 때 미리 어떤 설정을 해주지 않으면
CORS 문제로 막히게 된다.
postman 이나 스프링에서 테스트할 때는 잘되는데 "웹사이트" 즉 서비스에서 보내게 되면 cors 오류가 뜬다.
이럴 때는 "어디에서 보낸 요청이 CORS로 막히는가" 를 찾아야한다.
브라우저, 프론트엔드에서 일어나는 문제
cors는 어떤 사이트에서 다른 사이트로 전달되는 api 요청을 풀어주는 역할이고,
sop 가 요청을 막는 역할을 한다. sop, same-origin policy 동일 출처 정책
cors 오류는 이게 되게 하려면 cors 정책을 허용해 주던가 해라 라는 뜻
동일 출처 정책과 반대 개념으로,
cors = 다른 출처간에 리소스를 공유할 수 있도록 하는 것
출처는 보내고 받는 각각의 위치 즉 웹사이트랑 api의 주소이고,
리소스는 주고받아지는 데이터이다.
즉 미친토끼닷컴과 네이버 지도 api 이 서로 다른 출처끼리 정보요청과 반환이 가능하도록 하는게 cors 이다.
원래 서로 다른 출처끼리 요청을 주고 받는건 안되는게 기본값이었다.
웹 개발이 다양해지고 기술이 발전했는데, 다른 사이트간의 요청들을 브라우저가 막고 있으니까
개발자들은 jsonp 등의 방식으로 이를 우회하는 꼼수들을 사용하기 시작했다.
그래서 이걸 합의된 출처들간에 합법적으로 허용해주기 위해
어떤 기준을 충족시키면 리소스 공유가 되도록 만들어진 메커니즘이
바로 이 cors, 교차 출처 자원 공유 방식이다.
그렇다면 어떤 기준을 충족 시켜야 하냐면,
요청을 받는 백엔드쪽에서 이걸 허락할 다른 출처들을 미리 명시해두면 된다.
백엔드 서버를 프로그래밍 할 때 쓰는 프레임워크들에 cors 옵션을 넣는 방법들이 쉽게 마련되어있다.
아무나 보내도 되는 요청의 경우 일반적인 방법으로 별표, 와일드카드를 적어놓으면 가능하다.
브라우저는 다른 출처끼리의 요청인 경우 요청에 origin 이라는 header를 추가한다.
또한 요청하는 쪽의 scheme과 도메인, 그리고 포트가 담긴다.
여기서 scheme 이란 요청할 자원에 접근할 방법,
이를테면 http, ftp, telnet 등을 말한다.
프로토콜이라도 한다.
https://하이.com 접속 시
https 가 scheme, 하이.com이 도메인, 그리고 그 뒤에 :000 등이 달려 있다면 포트이다.
이 요청을 받은 네이버지도 api 서버는 답장의 헤더에 지정된 access-control-allow-origin 정보를 실어서 보낸다.
만약 하이.com 이 등록된 상태면 그 url도 들어있다.
그러면 이제 크롬이 이 두개를 비교해서 오리진에 보낸거가 똑같이 있다면 오케이 해준다.
origin에서 보낸 출처값이 서버의 답장 헤더에 담긴 access-control-allow-origin에 똑같이 있으면
안전한 요청으로 간주하고 응답데이터를 받아오게 된다.
없으면 cors 오류가 뜬다.
그리고 토큰 등 사용자 식별 정보가 담긴요청에 대해서는 보다 엄격하다.
일단 보내는 측에서는 요청의 옵션에 credentail 항목을 true로 세팅해야하고
받는쪽에서는 아무출처나 다 허용하는 와일드카드가 아니라
보내는 쪽의 출처-웹페이지 주소를 정확히 명시한 다음
access-control-allow-credentials 항목을 true로 맞춰야한다.
그리고 이 방식은 simple request 라고 해서 get 이나 post등 일정 조건의 요청들에 사용되는것이다.
put이나 delete등 이와 다른 요청들은 본 요청을 보내기 전에
preflight 요청이란걸 먼저 보내서 본 요청이 안전한지 확인하고
여기서 허락이 떨어져야 본격적으로 요청을 보낼 수 있다.
서버의 데이터에 영향을 줄 수 있기 때문이다.
정리, cors 의 요청은 두 종류
1) simple request (get, post)
요청을 보내기는 다 보내지만 통과를 못하면 답장만 못받아온다.
2) preflight request (put, delete)
요청을 보내는 것도 허락을 받아야한다.