-
[Node] 동일 출처 정책과 CORS와 에러 해결법programing/Language 2019. 7. 29. 11:54
안녕하세요, Einere입니다.
(ADblock을 꺼주시면 감사하겠습니다.)
이번 포스트에서는 프론트에서 http 요청을 할 때 심심하면 나오는 CORS문제 해결법에 대해 알아보도록 하겠습니다.
동일 출처 정책(same origin policy)
Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin.
An origin is defined as a combination of URI scheme, host name, and port number.
This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model.특정 웹 페이지에서 자원을 요청할 때, 출처(origin)가 같은 경우에만 해당 자원에 접근할 수 있는 정책입니다.
여기서 출처가 동일하다는 것은 다음 세 가지가 동일해야 함을 의미합니다.
- URI scheme(protocol, ...)
- host name
- prot number
만약 같은 출처라면 http요청이 자유롭지만, 다른 출처에 요청을 한다면 반드시 요청받는 쪽에서 요청하는 쪽의 요청을 허용해야 합니다.
CORS(Cross-Origin Resource Sharing)
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin.
A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) than its own origin.CORS는 http 헤더에 다른 출처에 존재하는 자원에 대한 접근권한을 추가하는 메커니즘을 의미합니다.
만약 어떤 웹 페이지가 자신과 다른 출처로 http 요청을 하게 된다면, 자동적으로 교차 출처(cross-origin) http 요청을 한다고 합니다. 더 자세히 말하자면, 브라우저에서 본래의 요청을 전송하기 전에 OPTIONS 메소드를 가진 요청을 preflight를 전송하여, 서버가 클라이언트를 허용하는지 안 하는지 확인합니다. 만약 거절당하면 콘솔에 CORS 에러를 출력하며, 허용되었다면 본래의 요청을 전송합니다.
특히 쿠키 같은 것을 이용해 자격증명을 하는 경우, 요청의 자격증명 모드를
include
로 설정해야 하는데, 이 요청 또한 교차 출처 요청을 합니다.클라이언트 측에서 CORS 에러를 안 나게 하는 법
`fetch API`를 이용해서 출처가 다른 특정 서버에 요청을 보내고 응답을 받는 코드를 구현을 하고 있었습니다. 그런데 자격증명 모드를
include
로 설정했더니 CORS에러가 발생했습니다.보통 쿠키를 이용한 자격 증명 및 접근 제어를 구현할 때 CORS 에러가 발생하며, 이를 해결하기 위한 방법이 요청의 자격증명 모드를
include
로 설정하는 것임을 생각했을 때, 의아했습니다.그래서 저는 한번
credential
의 옵션을 기본값인same-origin
으로 설정했더니 CORS 에러가 발생하지 않았습니다. 왜 이런 현상이 발생하는지 궁금해서 구글링을 해봤습니다.MDN의 CORS문서의 단순 요청(simple request) 섹션을 보면, 단순 요청은 CORS preflight를 트리거하지 않는다고 나와있습니다. 즉, 제가 보낸 요청의 자격증명 모드를
same-origin
으로 했을 때, 단순 요청이 되어서 CORS 에러가 발생하지 않은 것입니다.CORS 문제 해결 방법
다음과 같은 방법들로 CORS 문제를 해결할 수 있습니다.
- 프론트에서 직접 다른 출처에 요청하는 것이 아니라, 같은 출처의 백에 요청을 한 뒤, 백에서 다른 출처로 요청을 한다. (즉, 요청을 서버한테 위임하는 것입니다.)
- 서버 측 요청 헤더에 Access-Control 관련 내용을 집어넣는다. (서버를 직접 개발할 수 없다면, 서버 담당자에게 문의 메일을 보내야겟죠..?)
만약 자신이 node 기반 서버를 구현을 하고 있다면, cors라는 라이브러리를 통해 쉽게 해결할 수 있습니다.
해당 모듈을 npm으로 설치한 뒤,
app.use(cors())
만 해주면 됩니다.참고
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
https://en.wikipedia.org/wiki/Same-origin_policy
https://www.npmjs.com/package/cors
'programing > Language' 카테고리의 다른 글
[JS] CanvasRenderingContext2D 정리 1 (0) 2019.08.01 [JS] 태스크 큐와 이벤트 루프 (0) 2019.07.31 [JS] spread operator을 이용한 객체 복사 (0) 2019.07.27 [JS] prototype을 이용한 상속 (3) 2019.07.27 [JS] state와 mutable, immutable (0) 2019.07.23 댓글