일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 은행
- 금투세
- FED
- 가계대출
- 코드잇
- 코드잇 스프린트
- 한국은행
- 미국
- 금융투자소득세
- react
- 개발자
- CS
- 경제
- 개발
- 프로젝트 회고
- 금리
- 가계부채
- 내수
- javascript
- js
- 경제신문읽기
- Next.js
- next
- typescript
- 기준금리
- 프론트엔드
- 코드잇 스프린트 9기
- 자바스크립트
- 리엑트 쿼리
- API
- Today
- Total
뭉균의 개발일지
[CS지식] CORS 에러란 무엇인가? 본문
🚪 들어가며
프론트엔드 개발을 하다보면 CORS 에러를 마주치는 순간들이 있습니다. 특히, 서버에게 API를 요청하는 과정에서 발생하기 쉽습니다. 이번 포스팅에서는 API를 요청하는 기술인 AJAX와 그 과정에서 발생할 수 있는 CORS에러에 대해 알아보겠습니다.
📌 AJAX란 무엇인가?
AJAX(Asynchronous JavaScript and XML)는 웹 페이지를 새로고침(리렌더링)하지 않고 서버와 데이터를 주고받는 기술입니다. 비동기적인 방식으로 서버에 요청을 보내고, 그 응답을 받아서 페이지를 동적으로 갱신할 수 있습니다.
AJAX의 동작은 XMLHttpRequest 객체나 최신 브라우저에서는 Fetch API를 통해 이루어집니다. 이 객체들은 웹 페이지가 새로고침 없이 서버에 HTTP 요청을 보내고, 응답을 받아서 동적으로 페이지를 업데이트할 수 있도록 합니다.
이렇게 AJAX를 통해 서버와 데이터를 주고 받는 과정에서 CORS 에러가 발생할 수 있습니다. 그럼 CORS가 무엇인지부터 알아보겠습니다.
📌 CORS란 무엇인가?
CORS(Cross-Origin Resource Sharing)는 한 출처(origin)에서 다른 출처로 리소스를 요청할 때 발생하는 제한을 해결하기 위한 정책입니다. 기본적으로 브라우저는 보안상의 이유로 동일 출처 정책(Same-Origin Policy)을 따릅니다. 하지만, 웹 애플리케이션이 외부 API와 데이터를 주고받을 필요가 있을 때 CORS가 필요합니다.
1. Cross-Origin의 정의와 예시
Cross-Origin은 웹 애플리케이션이 한 출처에서 다른 출처의 리소스에 접근할 때 발생하는 개념입니다. 여기서 출처(origin)는 세 가지 요소로 결정됩니다.
- 프로토콜 (예: http vs https)
- 호스트(도메인 이름) (예: example.com vs api.example.com)
- 포트 번호 (예: :80 vs :8080)
서로 다른 프로토콜, 호스트, 포트를 가질 경우 다른 출처로 간주되며, 한 출처에서 다른 출처로 리소스를 요청할 때 이를 Cross-Origin 요청이라고 합니다.
위의 두 출처는 서로 다른 출처로 간주되며, 출처 A가 출처 B에 리소스를 요청하면 Cross-Origin 요청이 발생합니다. 이때, 동일 출처 정책에 따라 이러한 요청은 기본적으로 제한됩니다.
2. 동일 출처 정책(Same-Origin Policy)의 설명과 그 한계
동일 출처 정책(Same-Origin Policy)은 웹 보안의 기본 원칙 중 하나로, 한 출처의 웹 페이지가 다른 출처의 리소스에 무분별하게 접근하지 못하도록 방지하는 정책입니다. 이 정책은 브라우저 수준에서 동작하며, 악의적인 스크립트가 사용자 정보를 도용하거나 외부 서버와 비정상적인 통신을 하지 못하게 합니다.
- 클라이언트가 다른 출처로 요청을 보내면 브라우저는 이 요청을 막고, 서버의 응답을 받아오지 못하게 합니다.
- 예를 들어, https://www.naver.com에서 실행 중인 자바스크립트가 http://www.nate.com의 데이터를 요청하려고 할 때, 브라우저는 보안상의 이유로 이를 허용하지 않습니다.
동일 출처 정책은 보안을 강화하는 데 매우 중요한 역할을 하지만, 웹 애플리케이션이 점점 더 복잡해짐에 따라 다른 출처의 API나 리소스에 접근해야 하는 상황이 자주 발생하게 되었습니다. 예를 들어, 클라이언트가 외부의 REST API에 데이터를 요청하거나, 제3의 리소스를 로드하는 경우가 있습니다. 이때 동일 출처 정책은 지나치게 제한적으로 작용할 수 있으며, 이에 대한 해결책으로 CORS가 등장하게 되었습니다.
📌 CORS 동작 원리
CORS는 클라이언트가 다른 출처에 요청을 보낼 때 서버가 이를 허용하는지를 확인하는 과정입니다. 특히, Preflight 요청은 안전하지 않은 HTTP 메소드나 커스텀 헤더를 사용하는 요청의 경우 사전에 서버의 허락을 받기 위해 OPTIONS 메소드를 통해 실행됩니다.
1. Preflight 요청
Preflight 요청은 브라우저가 실제 Cross-Origin 요청을 보내기 전에 서버에게 요청을 보내어 해당 요청이 허용되는지를 확인하는 과정입니다. 이는 특히 안전하지 않은 HTTP 메소드(예: PUT, DELETE)나 커스텀 헤더를 사용할 때 발생합니다. 이것의 진행과정은 다음과 같습니다.
- 클라이언트 요청: 클라이언트가 CORS 요청을 시도할 때, 브라우저는 먼저 Preflight 요청을 보내야 하는지 결정합니다.
- Preflight 요청 전송: 브라우저가 OPTIONS 메소드를 사용하여 Preflight 요청을 서버에 보냅니다. 이 요청에는 Origin 헤더가 포함되어, 요청이 어떤 출처에서 오는지를 서버에 알립니다.
- 서버 응답: 서버는 Preflight 요청을 수신하고, 요청을 허용할 경우 관련 CORS 헤더를 포함한 응답을 보냅니다. 이때, Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers 등이 포함됩니다.
- 클라이언트 처리: 브라우저는 서버의 응답을 확인하여, 요청이 허용되었는지 판단합니다. 허용된 경우에만 실제 요청을 진행합니다.
2. CORS 요청의 전체적인 흐름
CORS의 전체적인 흐름을 정리하면 다음과 같습니다.
- 클라이언트: 사용자가 웹 페이지에서 특정 동작을 실행하여 서버에 요청을 시작합니다.
- Preflight 요청: 브라우저는 요청이 안전한지를 확인하기 위해 OPTIONS 메소드를 사용하여 Preflight 요청을 서버에 보냅니다.
- 서버 응답: 서버는 Preflight 요청에 대해 허용 여부를 포함한 응답을 보냅니다 (예: CORS 헤더)
- 실제 요청: Preflight 요청이 허용되면, 브라우저는 실제 요청을 서버에 보냅니다 (예: GET, POST)
- 서버 응답: 서버는 실제 요청에 대한 응답을 클라이언트에게 보냅니다.
- 클라이언트 처리: 클라이언트는 서버의 응답을 받아 웹 페이지를 업데이트하거나 필요한 작업을 수행합니다.
📌 CORS 에러 발생 이유
CORS 에러는 웹 애플리케이션이 Cross-Origin 요청을 수행할 때 발생하는 문제로, 주로 서버 설정과 브라우저의 보안 정책으로 인해 발생합니다.
1. 서버 설정 문제
CORS 요청이 실패하는 주된 이유 중 하나는 서버에서 적절한 CORS 헤더가 설정되어 있지 않기 때문입니다. 서버는 클라이언트의 요청을 수락하기 위해 적절한 CORS 정책을 설정해야 합니다.
2. 브라우저의 보안 정책
CORS는 웹 보안의 일환으로 브라우저에서 구현된 보안 정책에 따라 작동합니다. 이 정책은 Cross-Origin 요청을 통해 발생할 수 있는 보안 위협으로부터 사용자를 보호하기 위해 설계되었습니다. 즉, 기본 원칙은 SOP이므로 Cross-Origin 요청이 있을 때, 에러를 발생시키는 것입니다.
📌 CORS 해결 방법
CORS 문제를 해결하기 위해 서버는 요청을 허용할 출처를 명시하는 헤더를 설정해야 합니다. 이를 위해 Access-Control-Allow-Origin 헤더에 허용할 출처를 지정하거나, 모든 출처를 허용하려면 *로 설정할 수 있습니다. 단, 자격 증명(쿠키, 인증 헤더 등)이 포함된 요청에서는 Access-Control-Allow-Origin에 특정 도메인을 지정해야 하며, *를 사용할 수 없습니다.
서버 설정을 변경하기 어려운 경우에는 프록시 서버를 사용해 CORS 문제를 해결할 수 있습니다.
1. 프록시 서버를 통한 CORS 해결 방법
프록시 서버는 클라이언트와 실제 서버 간의 중개 역할을 하며, CORS 문제를 우회하는 대체 솔루션으로 사용될 수 있습니다. 클라이언트가 프록시 서버로 요청을 보내면, 프록시 서버는 이를 실제 대상 서버에 전달한 후 응답을 받아 다시 클라이언트로 전달합니다. 이렇게 하면 클라이언트는 CORS 문제 없이 프록시 서버를 통해 원하는 리소스를 요청할 수 있습니다.
2. 프록시 서버 설정 방법
프록시 서버에서 CORS 헤더를 추가하면 클라이언트가 요청한 리소스를 올바르게 전달할 수 있습니다. Node.js의 http-proxy-middleware와 같은 라이브러리를 사용하면 쉽게 프록시 서버를 설정할 수 있습니다. 아래는 http-proxy-middleware를 사용한 예시입니다.
// 예시: Node.js Express에서 http-proxy-middleware 사용
const { createProxyMiddleware } = require('http-proxy-middleware');
const express = require('express');
const app = express();
app.use('/api', createProxyMiddleware({
target: 'https://target-server.com', // 실제 요청을 보낼 서버
changeOrigin: true, // 대상 서버로부터의 응답 헤더를 변경
onProxyReq: (proxyReq, req, res) => {
// 필요 시 추가적인 요청 헤더를 설정
},
onProxyRes: (proxyRes, req, res) => {
// 응답 헤더에서 CORS 관련 헤더 추가
res.setHeader('Access-Control-Allow-Origin', '*');
}
}));
app.listen(3000, () => {
console.log('프록시 서버가 3000번 포트에서 실행 중입니다.');
});
위 예시에서는 /api로 들어오는 모든 요청을 https://target-server.com으로 프록시 처리하며, Access-Control-Allow-Origin 헤더를 설정해 모든 출처에서의 요청을 허용합니다.
📌 결론
이번 포스팅을 통해 CORS에 대해 알아봤습니다. CORS는 현대 웹 개발에서 필수적인 개념으로, 특히 외부 API와 통신하는 애플리케이션에서는 반드시 고려해야 할 요소입니다. CORS 문제를 효과적으로 해결함으로써 애플리케이션의 안정성을 높이고, 원활한 사용자 경험을 제공하는 것이 중요한 것 같습니다.
'CS' 카테고리의 다른 글
[CS지식] 쿠키 vs 로컬 스토리지, 무엇이 다를까? (9) | 2024.10.26 |
---|---|
[CS지식] 일반 함수와 화살표 함수의 차이점 (2) | 2024.10.03 |
[CS지식] 객체지향 프로그래밍이란? (1) | 2024.09.10 |