이 글은 CORS에 대해 적은 글입니다. 이 포스팅을 포함해 게시된 모든 포스팅의 큰 주제는 순차적인 흐름을 지키지 않습니다. 혼란에 주의해 주세요!
예전에 React를 이용하여 프로젝트를 진행하다 팀원 중 한 명이 CORS와 관련된 이슈와 마주한 적이 있었다. 당시 개발 초보자였던 우리에겐 이 이슈는 너무 강적이었기에 오로지 이슈 해결에만 집중하였고, CORS에 대한 개념을 정리하지 못했었다. 오늘은 그때 간과했던 부분들을 되짚어보고자 CORS에 대해 포스팅해보겠다.
CORS
Cross-Origin Resource Sharing
CORS는 W3C에서 서로 다른 Origin에서 자원(Resource)을 공유할 수 있도록 하기 위해 내놓은 정책을 말한다. 여기서 서로 다른 Origin이라는 것은 도메인 또는 포트가 다르다는 것을 의미하기 때문에 서로 다른 도메인 주소 사이에서 데이터(API 요청과 응답)를 주고받을 수 있도록 하기 위한 정책이라고 말할 수 있다.
🤔잠시, 간단하게 용어 정리하고 넘어가자!
- W3C
World Wide Web Consortium의 약어로 월드 와이드 웹(WWW)을 위한 표준을 개발하는 국제 컨소시엄을 말한다.
- 도메인
인터넷에 연결되어 있는 장치들은 각각을 식별할 수 있는 주소를 가지고 있다. 이것을 ip라고 하는데, 각 ip를 쉽게 기억하고 접근할 수 있게 부여된 이름을 도메인이라고 한다.
- 포트
컴퓨터에는 여러 개의 서버가 설치될 수 있다. 이때 우리가 컴퓨터에 접속할 때 서버와 서버끼리 구분할 수 있는 방법이 필요한데, 이것을 위해 준비된 개념이 포트다. 위에 도메인에서 언급된 ip가 컴퓨터에 접속하는 주소라면, 포트는 컴퓨터 안에 설치된 서버에 접속하는 주소라고 생각하면 된다.
CORS가 등장한 이유
CORS가 등장한 이유는 바로 Same-Origin Policy(동일 출처 정책)때문이다. 이 정책은 어떤 출처에서 문서 혹은 스크립트가 다른 출처에서 가져온 자원(Resource)과 상호작용 하는 것을 제한하는 보안 방식을 말한다. 그러니까 쉽게 설명하면, 서로 다른 Origin(다른 도메인, 포트)에서 자원 공유를 보안 이슈로 인해 제한한다는 의미다.
위의 정책을 적용하면 다른 Origin에서 자원 요청이 불가능해지므로 공격받을 수 있는 경로를 제한하거나 해로운 문서들을 분리할 수 있어 확실한 보안상의 이점이 있다. 그러나 SPA(Single Page Application, 이전 CSR 포스팅을 다루며 언급했었다!)의 등장으로 클라이언트, 서버의 도메인을 따로 유지하는 경우가 발생하였다. 이뿐만이 아니다. 외부 API를 연동하여 사용하는 경우엔 App와 외부 API의 Origin이 다르기 때문에, Same-Origin Policy로 인해 자원 공유가 불가능한 상황이 발생한다. 하지만, CORS를 활용하면, 위의 보안 문제들을 예방하고 내가 허용하는 Origin만 요청할 수 있게 된다.
CORS 동작 과정
브라우저에서 자원을 요청할 때, 추가적인 헤더에 정보를 담는다. 이때, 내 Origin이 무엇이고 어떤 메소드를 사용하여 요청할 것인지, 어떤 헤더들을 포함할 것인지를 담아 서버에 전송한다. 그리고 서버에서는 서버가 응답할 수 있는 Origin들을 헤더에 담아 브라우저에게 전송한다. 브라우저는 이 헤더를 참고하여 해당 Origin에서 요청할 수 있는지 판단하고 가능하다면 자원(Resource) 전송을 허용하고, 불가능하다면 에러를 발생시킨다.
CORS 설정 방법
😰 해당 부분을 설명하기 앞서...
해당 과정은 Node.js 부분의 내용이 포함되어 있다. 솔직히 난 Node.js를 다룰 줄 모른다. 하지만, 포스팅 머리글에서도 말했지만 CORS 이슈를 경험한 적이 있고 멘토님들과 구글에게 99% 도움을 받아 해결하였다. 하지만, 다시 이런 상황이 반복되거나 다른 이슈들을 만났을 때, 항상 도움만 받으면 성장을 기대할 수 없다. 그래서 언제나 오류에 대처할 수 있도록, 많이 참고하였던 블로그와 공식 문서를 참고하여 내용을 정리해 보았다.(참고 부탁드립니다...)
등장 이유 부분에서 언급했던 내용으로 문서 혹은 스크립트는 Same-Origin Policy(동일 출처 정책)을 따른다고 했다. 따라서 따로 CORS정책을 허가하는 조건들을 추가해야 다른 Origin과 자원 공유를 할 수 있다. CORS를 설정하는 방법엔 크게 2가지가 있다.
- Access-Control-Allow-Origin response를 활용한다.
Express서버(Express.js...🤢 Node.js 의 프레임워크다🤢🤢🤢)에서 API의 응답 헤더에 "Access-Control-Allow-Origin" 값을 넣어서 CORS정책을 따르도록 하는 방법이 있다.
모든 Origin을 허가할 때
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
});
특정 Origin을 허가할 때
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "특정 url 주소");
});
🤢Node.js ? Express.js?
Node.js
Backend 서버 기술로 Frontend 쪽만이 아닌 Backend 쪽에서도 JavaScript기술을 쓸 수 있게 고안된 언어.
Express.js
Node.js의 프레임워크. 위의 Express서버는 이 프레임워크를 활용하여 구축한 서버를 말한다.
2. CORS 라이브러리 설치
Express서버에서 CORS 라이브러리를 설치하여 적용하는 방법이 있다. 아래의 인용문을 참고해보자.
라이브러리 설치
npm i cors
특정 Origin에 적용하기
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({ origin: "특정 url 주소" }));
모든 Origin에 적용하기
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
정리
CORS란?
CORS란 Cross Origin Resource Sharing의 약자로 브라우저의 현재 웹 페이지가 이 페이지를 받은 서버가 아닌 다른 서버의 자원을 호출하는 것을 의미한다.
CORS 이슈는 왜 발생하는가?
Same-Origin Policy(동일 출처 정책) 때문에 CORS 같은 상황이 발생하면 외부 서버에 요청한 데이터를 브라우저에서 보안 목적으로 차단 한다. 그로 인해 정상적으로 데이터를 받을 수 없는 상황이 발생하여, CORS 정책을 적용하여 해결해줘야 한다.
'ivory's DevLog' 카테고리의 다른 글
Babel (0) | 2020.10.18 |
---|---|
[JavaScript] - this (0) | 2020.10.04 |
SSR(Sever Side Rendering)과 CSR(Client Side Rendering) (1) | 2020.09.30 |
Cookie? Local, Session Storage?? (0) | 2020.09.25 |
브라우저 렌더링 과정 (0) | 2020.09.23 |