protocol + host + port 가 동일한 url의 경우 같은 origin(출처)라고 합니다
[다른 출처 #1, 프로토콜이 다름]
https://naver.com
http://naver.com
[다른 출처 #2, 호스트가 다름(실제로는 동일하지만 브라우저에서 string 비교할 때 다르게 인식)]
http://localhost:8081
http://127.0.0.1:8081
[다른 출처 #3, port가 다름]
localhost:8080
localhost:8081
[같은 출처, path만 다름]
http://naver.com
http://naver.com/login
동일 출처의 리소스로만 상호작용을 제한하는 브라우저의 보안 정책입니다.
악의적일 수 있는 문서를 분리함으로 공격 경로를 줄여줍니다.
example
1. 페이스북에 로그인 후 인증토큰을 받아옵니다
2. 메일에서 악의적인 페이지(hack.com)에 접속하게 되었습니다
3. 악의적인 페이지에서 인증토큰을 이용해 페이스북에 포스트를 올리는 요청을 보냅니다
4. 이때 SOP 정책이 없는 경우 이슈가 발생합니다
IE의 경우는 SOP에 몇가지 예외사항이 있습니다.
1. 양쪽 도메인 모두 신뢰할 수 있는 사이트(높은 단계의 보안 수준)인 경우 SOP를 적용하지 않습니다
2. SOP 검사에 포트를 포함하지 않습니다
페이지를 만들다 보면 다른 출처의 자원이 필요한 경우가 생깁니다. 하지만 브라우저에서는 SOP로 인해 다른 출처의 자원과 상호작용이 제한됩니다.
CORS는 HTTP 헤더를 사용해 한 출처에서 실행중인 웹 어플리케이션이 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 브라우저에게 알려주는 mechanism 입니다.
서버 데이터에 부수 효과(side effect)를 일으킬 수 있는 HTTP 요청 메서드(GET을 제외한 HTTP 메서드)에 대해, CORS 명세는 브라우저가 요청을 OPTIONS 메서드로 "프리플라이트"(preflight, 사전 전달)하여 지원하는 메서드를 요청하고, 서버의 "허가"가 떨어지면 실제 요청을 보내도록 요구하고 있습니다.
simple request의 경우는 CORS preflight를 트리거하지 않습니다(ex. 별도의 side effect가 없는 get 요청).
simple request는 다음 조건을 모두 충족해야 합니다
Simple Request 헤더
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Origin
헤더를 request에 추가합니다Simple Response 헤더
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[…XML Data…]
Cache-Control
, Content-Language
, Content-Type
, Expires
, Last-Modified
, Pragma
Access-Control-Expose-Headers
라는 헤더를 보내줘야만 합니다CORS가 허용되는지 먼저 preflight 요청을 통해 체크합니다
Origin
헤더를 request에 추가합니다자바스크립트로 크로스 오리진 요청을 보내는 경우, 기본적으로 쿠키나 HTTP 인증 같은 자격 증명(credential)이 함께 전송되지 않습니다.
서버에서 이를 허용하고 싶으면, 자격증명이 달린 헤더를 명시적으로 허용하겠다는 세팅이 서버에 필요합니다.
자격증명을 함께 전송하는 방법
credentials: include
withCredentials: true,
자격 증명 정보가 담긴 요청을 서버에서 받아들이기로 동의했다면 서버는 응답에 Access-Control-Allow-Origin 헤더와 함께 Access-Control-Allow-Credentials: true 헤더를 추가해서 보냅니다.
자격 증명이 함께 전송되는 요청을 보낼 땐 Access-Control-Allow-Origin에 *을 쓸 수 없습니다.
https://ko.javascript.info/fetch-crossorigin
https://ui.toast.com/weekly-pick/ko_2021110
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS