WEB

CORS?

prefer2 2022. 10. 9. 20:31

 

웹개발을 하다보면 한번쯤은 만나는 녀석 CORS에 대해 알아보자!

 

 

동일 출처 정책(Same-Origin Policy)


어떠한 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 정책. 두 URL의 프로토콜, 포트, 호스트가 모두 같아야 동일한 출처라고 말한다. 예를 들어 알아보자.

http://example.com/a/a.html 과 동일한 출처인지를 비교하는 예시이다.

 리소스 요청 허용 여부  이유
 http://example.com/b/other.html  경로만 다름
 http://example.com/a  경로만 다름
 https://example.com/another.html  프로토콜이 다름
 http://example.com:81/a/a.html  포트 다름(기본 포트 80)
 http://different.com/a/a.html  호스트 다름

보안상의 이유로 브라우저는 교차 출처 HTTP 요청을 제한하고, XMLGttpRequest와 Fetch API는 이런 동일 출처 정책을 따른다.

 

왜 동일 출처 정책이 필요할까?

해커가 악성 코드를 사용해 쿠키를 탈취하여 해커의 사이트에서 해당 정보를 사용해 자신에게 돈을 이체하거나 하는 일이 방생할 수도 있기 때문이다. 이를 막기 위해 신뢰할만한 출처와만의 통신이 필요한데 동일 출처 정책은 잠재적으로 해로울 수 있는 문서를 분리하여 공격받을 수 있는 경로를 줄여준다.

개발을 하다보면 외부 API를 사용하는 경우도 있고, 포트를 바꿔 사용하는 경우도 있는데 동일 출처 정책으로 인해 불편함을 느낄 수 있다. 이런 불편을 해결하기 위해 등작한 것이 Cross-Origin Resource Sharing(CORS) 정책이다.

 

 

 

CORS?


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

서버가 same origin 정책(same-origin policy)을 완화할 수 있게 해 주는 표준입니다.

a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served.

 

HTTP 헤더를 사용하여 클라이언트와 서버로 하여금 서로에 대해 인지하고 한 출처에서 다른 출처의 자원을 사용할 수 있게 하는 메커니즘이다. CORS의 동작 방식에는 Simple requesets, Preflighted requests가 있다

 

Simple Request

아래의 3가지 조건을 모두 만족하면 simple request

  • GET. HEAD, POST 메서드 중 한가지
  • 수동적으로 설정 가능한 헤더는 Accept, Accept-Language, Content-Language, Content-Type, Range이다
  • Content-Type 헤더의 값이 application/x-www-form-urlencoded, multipart/form-data, text/plain여야 한다.

위 조건을 만족하는 요청을 보내게 되면 simple request가 된다. 예를 들어 https://foo.example에서 https://bar.other로의 호출을 하게되면 서버가 클라이언트 origin에 대해 CORS가 적용되어있는지 확인(Access-Control-Allow-Origin: https://foo.example 이 되어있는지)하고 동시에 요청된 작업까지 수행한다.

 

Preflighted Request

OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인한다. cross-origin 요청은 유저 데이터에 영향을 줄 수 있기 때문에 미리 전송(preflighted)한다.

CORS가 잘 적용되어 있는 서버에 preflight request를 보내면 추가적인 요청이 생기는 것으로 생각될 수도 있다. 이와 같은 요청은 CORS가 적용되어 있지 않은 서버들을 보호하기 위해 preflight request를 하여 서버에게 불필요한 작업이 일어나지 않도록 해준다.

 

 

 

CORS 적용하기


Access-Control-Allow-Origin 설정

살펴보았듯이 http header에 Access-Control-Allow-Origin을 설정하여 허용할 오리진을 명시해 CORS를 적용할 수 있다. 서버에서 직접 헤더에 추가만 해주면 해당 오리진으로부터 오는 요청에 대해서는 정상적인 응답을 할 수 있게 된다.

Access-Control-Allow-Origin: http://example.com

 

CRA

백엔드에서만 설정을 해줄 수 있는 줄 알았는데 CRA를 사용하면 서버측이 아닌 클라이언트 측에서도 CORS 설정을 추가해줄 수 있다. package.json에 proxy를 설정해주면 된다. 이렇게 하면 내가 직접 서버에 요청을 보내는 것이 아니라 설정한 주소로 서버에 요청을 보내는 형태가 된다. 개발 단계에서 사용하기에 좋을 것 같다.

https://create-react-app.dev/docs/proxying-api-requests-in-development/

 

 

참조


https://developer.mozilla.org/ko/docs/Web/HTTP/CORS/Errors

https://en.wikipedia.org/wiki/Cross-origin_resource_sharing

https://darnton.co.nz/2020/07/13/cors-proxy-for-client-side-blazor/

 

 

반응형

'WEB' 카테고리의 다른 글

SEO(검색 엔진 최적화)  (0) 2022.12.26
MVC 패턴이란?  (0) 2021.10.15
Virtual DOM  (0) 2021.09.02
HTTP 메시지(요청, 응답)  (0) 2021.08.25