- Published on
CORS란 무엇인가
- Authors
- Name
- Deokgoo Kim
들어가기 전
Same-Origin 정책에 의해 Origin이 같지 않으면 HTTP 요청을 하는 것이 어려웠습니다. 이를 우회하기 위해 나온 방법이 JSONP(2005년에 제안되었습니다)입니다. 그 이후 공식적으로 지원하는 것이 CORS(2014년 1월에는 W3C 권장 사항으로 승인되었습니다)입니다.
본론
먼저 SOP(Same-Origin Policy)를 알아야 합니다.
SOP(Same-Origin Policy)에 의해 프로토콜, 호스트, 포트가 모두 같아야 리소스 요청이 가능합니다. SOP는 웹 브라우저와 API 서버의 관계에서 발생하며 서버 간의 관계에서는 발생하지 않습니다. 유저의 안전벨트와 같은 기능을 하고 있습니다. 브라우저에 따라 옵션을 통하여 SOP를 거부할 수 있습니다. (자세한 내용은 위키)
최근 앱들을 보면 아래와 같이 API 레이어
와 프론트 레이어
를 분리하는 케이스가 대부분입니다.
- 웹 브라우저 - API 서버
- 웹 브라우저 - 웹 서버 - API 서버
1번의 경우에는 도메인이 다르면 리소스 요청이 되지 않습니다. 2번의 경우에는 웹 서버가 API 서버를 받게 된다면 문제가 될 것 없습니다. API 서버의 리소스를 단순히 웹 서버가 전달하는 역할이라면 1번의 형태로 요청을 하는 것이 일반적인 사고일 것입니다.
JSONP(JSON with Padding) - SOP를 우회하자
JSONP는 JSON 데이터를 SOP에 상관없이 불러올 수 있다는 것을 이용하는 방식입니다. JSON 데이터라고 해도 직접적으로 HTTP 요청을 할 경우에는 에러가 발생하지만 script 태그를 이용한다면 받아올 수 있습니다. (JSON 데이터를 그대로 script 태그에 넣으면 에러가 발생하므로 유효한 JS 문법으로 감싸야 하는 번거로움이 생깁니다.)
CORS(Cross-Origin Resource Sharing) - 공식 허용 방식
CORS는 공식적으로 출처가 다른 리소스를 접근할 수 있는 권한을 부여하도록 하는 체제입니다. 따라서 공식적으로 HTTP 요청을 통하여 진행되며 허용된 요청인지 확인하는 절차가 진행됩니다. (즉, 요청은 두 번 이루어집니다: Preflight Request, Main Request)
HTTP Method('OPTIONS')를 요청합니다. 이것은 아래의 것들을 포함하여 확인합니다.
- HTTP Header("Access-Control-Request-Method")
- HTTP Header("Access-Control-Request-Headers")
- HTTP Header("Origin")
Preflight Request (사전확인 요청)
OPTIONS /server/resource
Access-Control-Request-Method: PUT // PUT이 허용되어 있는가
Access-Control-Request-Headers: origin // 허용하는 header인가
Origin: https://duck-blog.netlify.com // 허용하는 origin인가
Preflight Response
HTTP/1.1 204 No Content
Connection: keep-alive // 끊지 않고 후속 요청이 가능
Access-Control-Allow-Origin: https://duck-blog.netlify.com // 허용하는 origin
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE // 허용하는 메소드
Access-Control-Max-Age: 10000 // 동일한 요청에 대한 응답을 선택적으로 할 수 있다.
결론
- 프로토콜, 호스트, 포트가 다르면 SOP에 의해 리소스 요청이 되지 않는다.
- SOP를 브라우저에 따라 무시할 수 있다.
- SOP는 서버 간의 통신에는 적용되지 않는다.
- CORS는 SOP를 허용하기 위하여 사용된다.
- CORS는 사전 요청과 메인 요청 두 번이 이루어진다.