
CORS(Cross-Origin Resource Sharing, 크로스-오리진 리소스 쉐어링)는 웹 페이지가 다른 도메인의 리소스에 접근할 수 있도록 허용하는 보안 메커니즘이다. 웹은 기본적으로 같은 출처 정책(Same-Origin Policy)을 따른다. 이 정책은 웹 페이지가 다른 도메인의 리소스를 요청할 때 보안상의 이유로 제한을 두는 것을 말한다. 예를 들어, 도메인 A의 웹 페이지가 도메인 B의 서버에 AJAX 요청을 보낼 때, 도메인 B의 서버는 이 요청을 거부할 수 있다.
CORS는 HTTP 헤더를 사용해 서버가 어떤 출처의 웹 페이지가 자신의 리소스에 접근할 수 있는지를 브라우저에 알려준다. 만약 서버가 CORS를 지원하고, 올바른 Access-Control-Allow-Origin 헤더를 포함하여 응답하면, 브라우저는 리소스에 대한 접근을 허용한다.
CORS가 생긴 배경에는 웹 애플리케이션의 복잡성 증가와 다양한 웹 서비스 간의 상호 작용 필요성이 있다. 예를 들어, 소셜로그인(카톡, 구글 로그인같은 것들), 컨텐츠 배포 네트워크(CDN), REST API 등은 다른 출처의 리소스를 안전하게 사용할 수 있어야 한다.
단순 요청(Simple Requests):
Origin 헤더를 요청에 추가한다.Access-Control-Allow-Origin 헤더를 포함한 응답을 반환한다.사전 요청(Preflight Requests):
OPTIONS 메소드를 사용해 사전 요청을 보낸다.Access-Control-Allow-Methods와 Access-Control-Allow-Headers를 포함한 응답을 반환하여 허용하는 메소드와 헤더를 알려준다.아래는 Node.js와 Express를 사용하여 CORS를 구현한 예시다.
const express = require('express');
const cors = require('cors');
const app = express();
// 모든 도메인에 대해 CORS를 허용할 경우
app.use(cors());
// 특정 도메인에 대해 CORS를 허용할 경우
app.use(cors({
origin: 'https://example.com' // 해당 도메인에서만 요청을 허용한다.
}));
// 동적으로 출처를 결정하는 경우
app.use(cors({
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));
app.get('/data', (req, res) => {
res.json({ message: 'This is CORS-enabled for all origins!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
이 코드는 cors 미들웨어를 사용하여 CORS를 적용한다. 첫 번째 app.use(cors());는 모든 출처의 요청을 허용한다. 두 번째는 특정 도메인에서만 요청을
허용한다. 세 번째는 출처를 동적으로 결정하여 허용하는 복잡한 예시다.
CORS는 웹 개발의 중요한 부분이며, 보안과 상호 운용성을 위해 필수적이다. 위 코드와 설명은 CORS의 기본적인 이해를 돕기 위한 것이며, 실제 웹 애플리케이션에서는 더 복잡한 시나리오와 보안 요구 사항을 고려해야 할 수 있다.

CORS는 여러 HTTP 헤더를 사용하여 작동한다. 이 헤더들은 요청이나 응답에 따라 다르게 사용되며, 각각의 헤더는 특정 목적을 가지고 있다.
요청 헤더(Request Headers):
Origin: 요청을 보내는 페이지의 출처를 나타낸다.Access-Control-Request-Method: 사전 요청에서 실제 요청에서 사용할 HTTP 메소드를 서버에 알린다.Access-Control-Request-Headers: 실제 요청에서 사용할 커스텀 헤더를 서버에 알린다.응답 헤더(Response Headers):
Access-Control-Allow-Origin: 어떤 출처의 리소스가 리소스에 접근할 수 있는지 나타낸다.Access-Control-Allow-Methods: 실제 요청에서 허용되는 HTTP 메소드를 나타낸다.Access-Control-Allow-Headers: 실제 요청에서 허용되는 헤더를 나타낸다.Access-Control-Allow-Credentials: 요청에 사용자 인증 정보(쿠키, HTTP 인증 및 클라이언트 SSL 인증서 등)를 포함할 것인지를 나타낸다.Access-Control-Max-Age: 사전 요청의 결과를 얼마나 오랫동안 캐시할 것인지를 나타낸다.웹 애플리케이션에서는 자바스크립트의 fetch API나 XMLHttpRequest 객체를 사용하여 CORS 요청을 처리할 수 있다. 아래는 fetch API를 사용한 예시다.
fetch('https://example.com/api/data', {
method: 'GET', // HTTP 요청 메소드
headers: {
'Content-Type': 'application/json',
// 필요한 경우 추가 헤더를 여기에 포함한다.
},
credentials: 'include' // 쿠키/인증 정보를 포함할 것인지 설정
})
.then(response => {
if (response.ok) {
return response.json(); // 응답을 JSON으로 파싱한다.
}
throw new Error('Network response was not ok.');
})
.then(data => {
console.log(data); // 응답된 데이터를 처리한다.
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
이 코드는 다른 도메인의 API로부터 데이터를 가져오는 간단한 GET 요청을 보내는 방법을 보여준다. credentials 옵션은 요청과 함께 쿠키나 인증 헤더를 보낼 것인지를 결정한다.