본문 바로가기

Coding/TIL (Today I Learned)

CORS(Cross-Origin Resource Sharing) 에 관하여

스프린트를 진행하면서 CORS라는 개념이 등장했다. 웹 개발을 위해서 알아야 할 기본적이고 중요한 이슈인 듯한데 짧은 세션 영상으로는 이것이 왜 필요한지, 언제 사용하는지 정확히 이해가 되지 않아서 조금 더 알아보고 정리해둔다.


CORS : Cross-Origin Resource Sharing?

추가 HTTP 헤더를 사용하여 브라우저에게 한 출처에서 실행 중인 웹 응용 프로그램의 다른 출처의 선택된 자원에 대한 접근 권한을 알려주는 메커니즘.이라고 MDN에 나와있지만 좀 어렵다.

예들 들면 현재 도메인과 다른 도메인으로 리소스가 요청되는 경우,

https://domain-a.com에서 제공되는 프런트 엔드 JavaScript 코드가 
XMLHttpRequest를 사용하여 https://domain-b.com/data.json를 요청하게 되면

 

이런 경우 보안상의 이유로 브라우저는 기본적으로 크로스 도메인 요청을 제한하고 있다. 이렇게 제한을 두게 된 까닭은,

옛날의 서버와 클라이언트는 서버에서 내려받은 클라이언트로만 통신을 했기 때문에 보안상의 의심의 여지가 없었다고 한다.

 

하지만 Single Page Application이 등장하고 웹이 고도화될수록 여러 곳에 있는 리소스를 활용할 필요가 생겼고, same origin 이 아니라 cross origin에서 서버 자원(리소스) 요청을 해야 했다. Single Page Application의 경우 비동기 네트워크 통신을 하기 때문에 API 서버와 웹페이지의 서버가 다를 수 있다. 따라서  API 서버로 요청을 할 시에 CORS 제한이 걸리게 된다.

웹 애플리케이션을 개선시키기 위해 개발자들은 브라우저 벤더사들에게 크로스 도메인 요청이 가능하도록 요구했고, 현재는 서버가 Allow 한 범위 내에서 cross origin요청을 허용할 수 있게 됐다. OPTIONS라는 메서드는 서버에서 Allow 하는 조건들을 다 맞추고 있는가를 사전에 서버에 확인하는 역할을 하는 것.

 

해결방법 

01. Access-Control-Allow-Origin

간단한 해결 방법은 API 서버의 응답 헤더를 변경해 주는 것이다.

서버의 해더 중 Access-Control-Allow-Origin이라는 프로퍼티에 CORS를 허용해 줄 도메인을 입력할 수 있다. 모든 곳에 CORS를 허용하기 위해서는 '* '(모든 도메인을 의미함)을 입력한다. 

Access-Control-Allow-Origin: *

이 코드를 아래와 같이 선언하고 활용할 수 있다.

const defaultCorsHeaders = {
  "access-control-allow-origin": "*",
  "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
  "access-control-allow-headers": "content-type, accept",
  "access-control-max-age": 10
};

//response.writeHead(statusCode, defaultCorsHeaders);

 

02. Express에서 CORS 허용하기

Express에서 CORS를 허용하기 위해서는 헤더를 직접 변경해 줄 수도 있고,

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

 

아래와 같이 Express의 CORS미들웨어를 사용할 수 있다.

Express를 활용한다면 헤더를 변경하기보다는 미들웨어 사용이 간편하다.

var express = require('express');
var cors = require('cors');
var app = express();

//모든 요청에 미들웨어 스택 cors()를 거치도록 설정한다.
app.use(cors());

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})