CORS(Cross-Origin Resource Sharing) 완벽 가이드
현대 웹 애플리케이션은 다양한 서비스와 통신하며 데이터를 주고받는 것이 일반적입니다. 하지만 웹 보안을 위해 도메인 간 통신을 제한하는 "동일 출처 정책(Same-Origin Policy)"이 존재합니다. 이를 안전하게 완화하여 외부 리소스와 통신할 수 있게 해주는 것이 바로 CORS(Cross-Origin Resource Sharing)입니다. 이 글에서는 CORS의 개념과 작동 원리, 실제 구현 방법 등을 자세히 설명합니다.
목차
1. CORS란 무엇인가?
cors란 무엇인가?
CORS는 Cross-Origin Resource Sharing의 약자로, 웹 브라우저가 다른 출처(origin)에서 리소스를 안전하게 요청할 수 있도록 허용하는 메커니즘입니다. 웹 보안의 기본 원칙 중 하나인 동일 출처 정책(Same-Origin Policy)은 보안 위협을 줄이기 위해 도메인, 프로토콜, 포트가 다른 출처 간의 리소스 공유를 제한합니다. 하지만 현대 웹에서는 다른 출처의 API나 리소스와 통신하는 것이 흔하며, 이를 안전하게 허용하기 위해 CORS가 도입되었습니다.
CORS의 핵심 개념
- 출처: 웹 페이지의 URL은 도메인, 프로토콜, 포트 번호를 포함하며, 이를 하나의 출처로 간주합니다. 동일한 출처가 아니면 브라우저는 기본적으로 리소스 요청을 차단합니다.
- 교차 출처 요청: 클라이언트가 다른 도메인(혹은 다른 출처)에서 리소스를 요청하는 행위를 말합니다. 예를 들어,
https://mywebsite.com
에서https://api.anotherwebsite.com
의 데이터를 가져오는 것은 교차 출처 요청에 해당합니다.
2. CORS가 필요한 이유
웹 애플리케이션은 점점 더 복잡해지고 있으며, 여러 서비스가 상호작용하는 구조로 발전하고 있습니다. 예를 들어, 웹 애플리케이션은 다른 출처의 API를 호출하여 데이터를 가져오거나, 클라우드 서비스에서 리소스를 로드할 수 있습니다. 그러나 동일 출처 정책(Same-Origin Policy)에 의해 이러한 요청이 차단될 수 있습니다.
동일 출처 정책은 악의적인 웹사이트가 사용자의 브라우저를 통해 다른 웹사이트의 민감한 데이터를 탈취하는 것을 방지하는 중요한 보안 메커니즘입니다. 하지만 이 정책은 모든 교차 출처 요청을 차단하기 때문에, 합법적이고 유효한 요청도 차단될 수 있습니다. CORS는 이러한 보안 문제를 해결하면서도 안전하게 다른 출처와의 상호작용을 가능하게 해줍니다.
3. CORS의 동작 방식
CORS의 작동 원리는 브라우저와 서버 간의 협력에 기반합니다. 브라우저는 교차 출처 요청을 할 때 서버에 요청을 보내고, 서버는 특정 헤더를 통해 요청을 허용할지 여부를 결정합니다.
CORS 요청 처리 과정
- 브라우저가 요청을 보냄: 클라이언트(브라우저)는 XMLHttpRequest나 Fetch API를 통해 교차 출처 요청을 보냅니다. 이때 브라우저는 요청에 Origin 헤더를 자동으로 추가합니다.
GET /data HTTP/1.1 Host: api.example.com Origin: https://mywebsite.com
- 서버의 응답: 서버는 요청을 받으면, 요청에 포함된
Origin
헤더를 확인하고, 해당 출처가 허용된 출처인 경우 Access-Control-Allow-Origin 헤더를 포함하여 응답합니다. HTTP/1.1 200 OK Access-Control-Allow-Origin: https://mywebsite.com Content-Type: application/json
- 브라우저의 검증: 브라우저는 응답에 포함된
Access-Control-Allow-Origin
헤더를 확인하여 요청한 출처가 허용된 출처인지를 검사합니다. 만약 헤더가 없거나 잘못된 경우, 브라우저는 응답을 차단하고 CORS 오류를 발생시킵니다.
4. CORS 관련 HTTP 헤더
CORS 동작에서 중요한 역할을 하는 HTTP 헤더는 다음과 같습니다:
- Origin: 요청을 보낸 출처를 나타냅니다. 브라우저가 자동으로 이 헤더를 추가하며, 서버는 이를 기반으로 요청을 허용할지 결정합니다.
- Access-Control-Allow-Origin: 서버가 해당 요청을 허용할 수 있는 출처를 명시합니다. 특정 도메인이나
*
(모든 출처)를 지정할 수 있습니다. - Access-Control-Allow-Methods: 클라이언트가 사용할 수 있는 HTTP 메서드를 지정합니다. 예를 들어,
GET
,POST
,PUT
등이 있습니다. - Access-Control-Allow-Headers: 클라이언트가 요청에 사용할 수 있는 커스텀 헤더를 정의합니다. 기본적으로 허용되지 않는 헤더는 여기에서 지정해야 합니다.
- Access-Control-Allow-Credentials: 클라이언트의 인증 정보(쿠키나 HTTP 인증 등)를 요청에 포함할 수 있는지 여부를 결정합니다.
- Access-Control-Max-Age: preflight 요청(사전 요청)의 결과를 얼마나 오랫동안 캐시할 수 있는지를 지정합니다.
5. CORS 에러 유형과 해결 방법
CORS는 브라우저 보안 정책에 의해 엄격하게 관리되며, 올바르게 설정되지 않으면 여러 오류가 발생할 수 있습니다. 가장 일반적인 CORS 에러와 해결 방법은 다음과 같습니다:
1. "No 'Access-Control-Allow-Origin' header is present on the requested resource"
- 원인: 서버가 클라이언트의 요청을 허용하지 않거나,
Access-Control-Allow-Origin
헤더를 반환하지 않았습니다. - 해결 방법: 서버에서 해당 출처를 허용하도록
Access-Control-Allow-Origin
헤더를 추가해야 합니다.
2. "Method not allowed by CORS"
- 원인: 서버가 요청한 HTTP 메서드를 허용하지 않았습니다.
- 해결 방법: 서버의
Access-Control-Allow-Methods
헤더에 요청한 메서드를 추가해야 합니다.
3. "Request header field [header] is not allowed by Access-Control-Allow-Headers"
- 원인: 클라이언트가 요청에 허용되지 않은 헤더를 포함시켰습니다.
- 해결 방법: 서버에서
Access-Control-Allow-Headers
헤더에 해당 헤더를 명시적으로 허용해야 합니다.
6. CORS 구현하기
프론트엔드 (JavaScript)
프론트엔드에서 CORS 요청을 보내는 방식은 Fetch API를 이용할 수 있습니다. mode: 'cors'
를 지정하면 브라우저는 교차 출처 요청을 허용합니다.
fetch('https://api.example.com/data', {
method: 'GET',
mode: 'cors',
credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
백엔드 (Node.js with Express)
백엔드에서는 cors
미들웨어를 사용하여 CORS를 간편하게 설정할 수 있습니다. 특정 출처나 메서드, 헤더를 허용하는 구체적인 설정이 가능합니다.
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://example.com',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
app.get('/data', (req, res) => {
res.json({ message: 'This is CORS-enabled' });
});
app.listen(8080, () => {
console.log('CORS-enabled server running on port 8080');
});
7. CORS와 보안
CORS는 보안을 강화하기 위한 메커니즘이지만, 잘못된 설정은 오히려 보안 취약점을 노출할 수 있습니다. 특히 Access-Control-Allow-Origin에 *
(모든 출처 허용)를 설정하면 위험할 수 있습니다. 중요한 API나 민감한 데이터를 다루는 경우에는 허용된 출처를 명확하게
지정하고, 필요하지 않은 요청은 제한하는 것이 중요합니다.
또한, CORS는 웹 애플리케이션의 모든 보안 문제를 해결하지 못하므로, 추가적인 보안 메커니즘(예: 인증, 권한 부여)을 함께 사용하는 것이 좋습니다.
'개발공부' 카테고리의 다른 글
비주얼 스튜디오(visual studio) 단축키 모음 (1) | 2024.10.10 |
---|---|
OAuth 란? (2) | 2024.10.01 |
http와 https의 차이점 (1) | 2024.09.25 |
JWT, Refresh Token, Access Token 이란? (2) | 2024.09.10 |
DCL, DML, DCL? (0) | 2024.09.04 |