2020. 4. 4. 08:00ㆍFrontend
Cross Origin Resource Sharing
CORS는 Cross-Origin Resource Sharing의 약자로 W3C에서 서로 다른 Origin에서 리소스(Resource)를 공유할 수 있도록 하기 위해 내놓은 정책입니다. 서로 다른 Origin 이라는 것은 도메인 혹은 포트가 다르다는 것을 의미하므로 서로 다른 도메인 주소 사이에서 데이터(예를 들면 API요청, 응답)를 주고받을 수 있도록 하기 위한 정책이라고 할 수 있습니다.
CORS이 등장하게 된 이유는 Same-Origin Policy (동일 출처 정책) 때문입니다. Same-Origin Policy는 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 보안 방식을 의미합니다. 간단히 말해서, 서로 다른 Origin에서의 자원 공유를 보안상의 이슈로 인해 제한하는 것입니다.
Same-Origin Policy : 웹 브라우저 보안을 위해 프로토콜, 호스트, 포트가 동일한 서버로만
ajax요청을 주고받을 수 있도록 한 정책
Same-Origin Policy를 적용하게 되면 다른 Origin에서의 자원 요청이 불가능해지기 때문에 공격받을 수 있는 경로를 제한하고, 잠재적으로 해로울 수 있는 문서들을 분리할 수 있기 때문에 보안상의 이점을 얻을 수 있습니다.
하지만 SPA(Single Page Application)의 등장하면서 클라이언트와 서버의 도메인을 따로 유지하는 경우가 자주 생기고(예를 들어 서버의 도메인이 http://api-service.com 클라이언트의 도메인이 http://service.com 인 경우), 또 외부 API를 앱 내에 연동하여 사용하는 경우에 앱과 외부 API의 Origin이 다르기 때문에 Same-Origin Policy에 의해 자원공유를 할 수 없는 상황이 생기게 됩니다.
기본적으로 HTML파일은 CORS정책을 따르도록 되어 있습니다. 따라서 추가적인 설정이 없이도 HTML <link> 태그를 통해 다른 HTML문서로 이동하거나 css파일의 정보를 가져오는 것이 가능합니다.
하지만 <script> 태그 내에 있는 HTTP 요청 (XMLHttpRequest, FetchApi)등은 기본적으로 Same-Origin Policy를 따르도록 되어 있습니다. 따라서 따로 CORS정책을 허가하는 조건들을 추가해주어야 다른 Origin과의 자원공유가 가능한 것입니다.
CORS 설정방법 (Express)
1. 서버단에서 특정 도메인에서의 요청을 허용해 준다.
Express서버에서 API의 응답 헤더에 "Access-Control-Allow-Origin" 값을 넣어줌으로써 CORS정책을 따르도록 할 수 있습니다. 모든 Origin에서의 요청을 허용할 수도 있고, 특정 Origin 에서의 요청만 허용할 수도 있습니다. 하지만 이 방법은 API에 대해서 개별적으로 적용되는 사항이기 때문에, 모든 API에 일일히 대응해주어야 한다는 단점 때문에 실제로는 2번방법을 더 선호합니다.
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인
res.header("Access-Control-Allow-Origin", "https://example.com"); // 특정 도메인
});
2. Node.js Express 미들웨어 CORS
CORS라이브러리를 Express 서버에 설치해서 사용하는 방법도 있습니다.
다음과 같은 명령어로 cors 라이브러리를 설치합니다.
npm i cors --save
설치한 후에 다음과 같이 사용할 수 있습니다.
app.use(cors());로 하게 되면 모든 Origin에서의 요청을 허용하므로, 특정 Origin을 제한하고 싶은 경우에는 Option들을 추가해주면 됩니다.
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
'Frontend' 카테고리의 다른 글
[OAuth] OAuth 2.0 (0) | 2020.07.04 |
---|---|
JIT vs AOT 컴파일러 (1) | 2020.06.16 |
[Crawler] Selenium으로 Everytime 크롤링하기 (1) | 2020.05.10 |
HTTPS란 (0) | 2020.05.05 |
Await vs Return vs Return Await (1) | 2020.04.06 |