728x90

CORS (Cross Origin Resource Sharing) 은 서로 다른 도메인 간에 리소스를 활용할 필요가 있을때, 어떤 규칙으로 누구에게 허용할 것인지를 정의하는 HTTP 표준의 일부입니다. 모던 브라우저들은 CORS 헤더에 대한 지원을 충실히 하고 있습니다만, 서버측에서는 어떤식의 구현이 필요한지, 그리고 커스텀 클라이언트를 사용하는 경우에는 어떤 요청을 보내는 것이 적절한지에 대해 오해도 많고 시행착오도 많습니다.

CORS 에 대한 기본적인 정의를 먼저 살펴보고 CORS 구현을 위한 RFC 규격을 살펴보면서 어떤 요청 헤더와 응답이 필요한지 살펴봄으로써, 혹시나 CORS 에 대하여 시행착오를 겪는 분들이 적어지기를 바라며 포스팅을 시작해 보도록 하겠습니다. 


CORS 란 무엇일까?

웹이 태동하고 급성장하던 시기에는 서로 다른 리소스를 가져다 쓰는 것에 대하여 큰 제약이 없었습니다. 하지만 리소스를 사용하는 것은 분명 서버측의 비용이 발생하는 일이고, 보안 관점에서도 접근하는 사용자를 적절히 통제할 필요가 생겼습니다. 이런 요구사항을 수용하기 위하여 정의된 것이 CORS (Cross Origin Resource Sharing, 서로 다른 원본 서버간의 리소스 공유에 관한 규칙) 입니다. 

2009년경에 출시된 파이어폭스 Firefox 3.5 와 사파리 Safari 4.0 에서부터 강화된 동일 오리진 정책 SOP (Same Origin Policy) 이 적용되기 시작했고 현재 시장에서 사용되는 대부분의 브라우저는 이 정책을 준수하고 있습니다. 이 즈음부터 XHR (XML Http Request) 을 이용해 서로 다른 원본 서버에서 리소스를 <비동기> 로 가져다 쓰는 것에 대한 혼란(?)이 시작되었다고 봐도 무방합니다. 

근래의 브라우저들에서는 Fetch 도 제공하기 시작했고 Fetch 역시 XHR 과 마찬가지로 CORS 의 영향권 아래에 있습니다. 따라서 CORS 에 대한 정확한 이해를 바탕으로 구현을 해야 커머셜 브라우저는 물론이고 커스텀 클라이언트 개발에 대응할 때도 불필요한 시행착오를 줄일 수 있습니다. 

브라우저보다 조금 늦게 (늘 그렇듯) 2010년에 Drafting 된 CORS

 

다른 Origin 에서 리소스를 가져오는 두가지 방법

JSONP 는 논외로 두고 다른 Origin 에서 리소스를 가져오는 방법은 앞서 이야기 한 것처럼 XHR 을 이용한 방식와 Fetch 를 이용한 방식으로 나뉘어 집니다. 많은 자바스크립트 프레임웍 (jquery, axios...) 도 이들을 래핑하고 있기 때문에 동일하게 CORS 규칙의 영향을 받게 됩니다. 

비동기로 리소스를 가져오는 방식은 다른 관점에서 보면 단순 요청 Simple Request 와 예비 요청 Pre-flight Request 로 다시 나뉘어 집니다. 이 두가지의 차이점은 간단합니다. 메소드와 헤더에 관한 규격들이 더 있지만, 일단 크게 아래의 구분이 있다는 점을 인식하는 것이 중요합니다. 

구분 내용
단순 요청 Simple Request - GET, POST, HEAD 메소드로 하나의 요청에 필요한 CORS 요청 헤더를 포함하여 전송
예비 요청 Pre-flight Request - OPTIONS 메소드를 이용하여 본 요청에 대한 스펙을 CORS 요청 헤더를 포함하여 전송
- 성공 응답을 받은 경우 본 요청을 전송

 

CORS 의 기본, Origin 요청 헤더

앞서 설명한 두 요청의 상세한 차이점은 다음 포스팅에서 소개할까 합니다. 절단 신공이라기 보다는... 두 요청의 공통 요소 중 하나인 Origin 헤더의 규격에 대해서 살펴보고 가는 것이 더 중요하기 때문입니다. 다른 Origin 으로 리소스를 요청하는 경우, 원래의 요청이 어떤 도메인에서 시작된 것인지를 다른 Origin 으로 알려주어야 할 필요가 있습니다. 이 때 사용하는 것이 Origin 요청 헤더입니다. 

가령 https://a-server.nopd-genius.com 이라는 도메인에서 XHR 혹은 자바스크립트 프레임워크를 이용하여 https://b-server.nopd-not.com 이라는 도메인으로 요청을 보내는 경우를 생각해 보겠습니다. 자바스크립트 코드는 첫번째 서버(a-server)에서 사용자 브라우저로 전달해 주었기 때문에, 이 코드가 만든 두번째 서버(b-server)로의 요청은 `Origin: https://a-server.nopd-genius.com` 이라는 헤더를 포함해야 합니다. 

이 요청을 받은 두번째 서버(b-server)는 Origin 값에 해당하는 정책을 확인하여 이를 CORS 응답 헤더로 내려주게 됩니다. 이 과정에서 Origin 헤더 값이 사전에 약속된 원본 도메인이 아니라면 에러 응답을 하거나 CORS 헤더 없이 응답하게 되어 결과적으로 브라우저에서는 응답을 사용하지 못하는 상황이 되게 됩니다. 

출처 : 모질라 CORS 문서 

 

그런데 말입니다, 모질라의 CORS 문서에서 발췌한 위의 내용은 한가지가 잘못되어 있습니다. RFC 의 규격 문서에 따르면 Origin 헤더의 값은 반드시 스킴 Scheme (http 혹은 https) 을 포함해야만 합니다. 위의 그림처럼 `Origin: foo.example` 로 던지면 규격에 대한 위반이 되게 됩니다. 왜냐하면 http://foo.example 과 https://foo.example 은 서로 다른 Origin 으로 활용될 수 있기 때문입니다. WHATWG 의 규격 문서를 보면 이 헤더의 규격은 아래와 같습니다. 

특정한 포트를 지정해주는 ":port" 는 필요 없는 경우 생략해 줄 수 있지만, 스킴은 생략 가능한 항목으로 명기되어 있지 않습니다. 따라서 Origin 요청 헤더는 위의 규격을 준수하여 전송할 필요가 있습니다. 모질라의 문서 그림도 업데이트가 되어야 하겠죠? ^^ 이렇게 Origin 헤더가 중요합니다. 

다행히도 근래의 모던 브라우저들은 CORS 요청을 하는 경우 항상 스킴을 포함한 Origin 요청 헤더를 보내주고 있습니다. 따라서 Origin 헤더 값은 상용 브라우저가 아닌 클라이언트를 사용하는 경우에 유의해 주시면 큰 문제는 발생하지 않을 것으로 생각됩니다. 다음 포스팅에서는 Simple Request 와 Pre-flight Request 의 요건에 대하여 보다 자세히 살펴보도록 하겠습니다. 


참고자료

 

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

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

 

 

Cross-Origin Resource Sharing

Must be deployable to IIS and Apache without requiring actions by the server administrator in a configuration where the user can upload static files, run serverside scripts (such as PHP, ASP, and CGI), control headers, and control authorization, but only d

www.w3.org

 

 

cross-site xmlhttprequest with CORS – Mozilla Hacks - the Web developer blog

Editor's Note: This article sure is a popular one! The Fetch API is now available in browsers and makes cross-origin requests easier than ever. Check out this Hacks post or ...

hacks.mozilla.org

 

 

Fetch Standard

 

fetch.spec.whatwg.org

 

728x90
728x90
트위터를 보고 있으면 정말 주옥같은 트윗들이 참 많이 올라옵니다. 시간내서 찾으려고 해도 찾기 힘든 소중한 정보들을 필터링해서 올려주시는 여러 전문가들의 자발적인 트윗은 정말 큰 힘이됩니다! 오늘 소개해드리는 링크들도 아마 여러 분들이 좋아하실 것 같습니다!

이 세상 대부분 Mobile 기기들의 에뮬레이터!

첫번째 소개해드리는 사이트는 Mobile Web Programming 이라는 블로그입니다. 오라일리에서 나온 Mobile Web 이라는 책을 쓴 저자의 블로그 이기도 합니다. 넘쳐나는 모바일 기기들을 하나하나 구입하는 건 사실상 불가능한 일. 에뮬레이터와 시뮬레이터로 기기 없이 왠만한 것은 테스트가 가능한 시대이지요! 하지만 그걸 찾는것도 번거롭다면 아래 링크를 참조해 보세요!



개발자와 디자이너를 위한 바탕화면 8종

포토샵, jQuery... 개발자와 디자이너라면 다들 한번씩 들어 봤음직한 이름들입니다. 이 도구들은 여러 전문 서적이나 레퍼런스를 통해서 배우고 사용할 수 있지만 단축키, 정리된 API 문서가 있으면 더욱 힘을 발휘하곤 합니다. 이런 정보를 바탕화면에 깔아두고 작업한다면 더욱 편리하겠지요? 개발자와 디자이너를 위한 바탕화면 8종 셋트는 바로 여러분을 위한 자료들입니다!


>>> 바로가기 : http://bit.ly/i1mBmn

- NoPD -
728x90

+ Recent posts