CORS (Cross-Origin Resource Sharing)
= 서로 다른 Origin 간에 데이터(Resource)를 주고받는 것.
BUT !응답 HTTP 헤더에 적힌, 데이터 열람 허용된 Origin 만 가능!
- Cross = 교차 = 서로 다른
- Origin = protocol + hostname + port = 요청 보내는(사용자 측)·받는(서버 측) 쪽의 url 일부
- Resource = Web Server 에서 제공하는 모든 데이터 (사용자의 데이터 등)
* 앞단에 Web Server를 두고 뒷 단에 WAS 를 두는 경우도 모두 포함하는 것
- Sharing = 공유 = 전송
CORS 에러
= 브라우저가 a.com 이라는 origin이 서버로부터 받은 응답에 접근할 권한이 없다고 판단해, a.com측(정확히는 js)에서 응답(데이터)에 접근하지 못하게 막으며(브라우저가 받은 응답 데이터를 a.com 에게 전달해주지 않으며) 발생시키는 에러
[에러가 발생하는 상황 흐름 예시]
1. 브라우저를 열고 a.com 이라는 origin 에서 서버로 요청을 보내는 js 를 실행함
2. 브라우저는 해당 요청을 서버로 보냄
3. 서버는 해당 요청에 대한 응답을 보냄. 여기서 a.com이 응답(리소스)에 접근 가능하다는 헤더를 붙여 보내지 않음
4. 브라우저가 응답을 받음
5. 브라우저가 응답의 헤더를 확인해 a.com 이 접근 권한이 없음을 확인.
6. 브라우저가 ⭐️a.com 에서 실행된 js 가 응답에 접근하는 것을 막음(응답을 js에게 전달해주지 않음) => CORS 에러 발생⭐️

- CORS 헤더를 사용하는 이유 = 브라우저의 기본 정책 중 '서로 다른 Origin 간에 요청 응답 주고 받을 수 없다'라는 Same-Origin Policy라는 보안 정책이 있어서 기본적으로 데이터 주고받기 불가. 그래도 브라우저가 리소스(데이터)를 소유하고 있는 웹서버에게는 특별히! 리소스(데이터)에 접근 가능한 특정 Origin을 지정할 수 있는 권한을 제공하는 차원으로 사용됨
- 브라우저에 Same-Origin Policy(SOP) 가 존재하는 이유
- 브라우저 내의 한 origin에서 불러온 js 가 다른 origin 의 리소스(쿠키, DOM, 데이터 등)에 접근하지 못하도록 막아서 민감한 정보 보호하기 위함
- +) 과거의 웹 서비스는 프론트와 백엔드를 같은 폴더에서 개발하고 같은 서버에 배포(모놀리식 구조)하는 경우가 잦았음 -> 그래서 보통 다른 Origin 에서 서버로 오는 요청은 의심스러운 요청인 경우가 많았음 -> 그래서 이러한 의심스러운 요청을 막기 위함
- Same-Origin Policy(SOP) 의 보호 대상
- 데이터 저장소: 쿠키, 로컬 스토리지
- 네트워크 응답
** SOP 보안 정책이 있지만, 위에서 봤듯이 브라우저가 요청 보내는 것 자체를 막는게 아님. 그래서 발생하는 문제가 CSRF(Cross-Site Request Forgery; 사이트 간 요청 위조) 공격.
응답 데이터를 읽을 필요 없이, 요청을 보내기만 하면 되는 경우에 피해가 발생함.
ex. bank.com 아 ##계좌로 **원 송금 보내
근데 내 서비스 프론트 - 백엔드 간에 요청 하는 데에도 origin 이 다른데 그러면 그냥 브라우저에서 다른 탭 간 요청 보내기 금지랑 같이 만들어놓지 왜 same-origin-security-policy를 만들었을까?
-> 탭은 어떤 리소스에 대한 소유·접근 범위를 정하는 단위가 될 수 없다.
이유 1. 하나의 탭(페이지) 안에도 여러 origin 이 있을 수 있다. (ex. iframe으로 다른 웹페이지를 삽입하는 경우)
이유 2. 서로 다른 탭에 같은 origin이 있을 수 있다.
Next.js에서 CORS 우회하기
CORS 에러가 브라우저의 보안 정책에 따라 브라우저가 만들어내는 에러임을 활용한다

0. next.config.js 설정 (Next.js 서버 설정)
아래와 같이 rewrites 설정을 해준다. /api 로 시작하는 fetch요청은 실제 API서버 경로로 요청을 보내도록 한다.(Proxy 역할)
import type { NextConfig } from "next";
const API_ORIGIN = process.env.API_ORIGIN;
const API_BASE_PATH = process.env.API_BASE_PATH;
if (!API_ORIGIN) {
throw new Error("API_ORIGIN is not set");
}
const nextConfig: NextConfig = {
reactCompiler: true,
async rewrites() {
return [
{
source: "/api/:path*",
destination: `${API_ORIGIN}${API_BASE_PATH ?? ""}/:path*`,
},
];
},
};
export default nextConfig;
1. 클라이언트에서 상대 경로로 fetch 요청
fetch 호출 시, 프로토콜(ex. https)과 호스트네임(ex. blog.naver.com) 제외, 엔드 포인트(ex. /api/todos)만 적어 요청을 보낸다
2. 브라우저의 동일 오리진 요청 활용
브라우저에서는 이를 동일 오리진에 보내는 요청으로 인식하여, 현재 오리진(페이지)을 서빙한 서버로 요청을 보낸다
= ⭐️ Next.js 서버(=Next.js를 배포한 서버 =현재 오리진)로 요청을 보낸다 ⭐️
=> 같은 오리진으로 요청을 보내는 것이므로 브라우저는 이를 CORS 정책 위반으로 간주하지 않는다
3. Next.js 서버의 프록시 역할
요청을 받은 Next.js 서버에서 rewrites 설정을 확인한다. 매칭되는 패턴(ex. /api)을 찾은 경우, next.config.js에 적힌 destination(API 서버의 url)로 요청을 보낸다. (중간에서 대리하여 요청 전달; Proxying)
4. 서버 간 통신으로 브라우저 보안 정책 우회
⭐️Next.js 서버 <-> API 서버 간의 통신은 브라우저 보안 정책 적용 범위가 아니므로 CORS 에러가 발생하지 않는다.⭐️ 이렇게 하면 서버 응답 헤더에 별도의 Access-Control-Allow-Origin 을 설정해주지 않아도 데이터를 받아올 수 있다.
+) Web Server와 Web Application Server 에 대하여

- Web Server = 정적 콘텐츠(html, css, js, 이미지 등)에 대한 요청이 들어올 때 응답. 동적 처리(데이터 변경 등)가 필요한 경우 WAS로 요청 넘김
- Web Application Server(WAS) = 동적 콘텐츠(js 버튼 클릭으로 변화하는 데이터, 실시간 날씨 정보, SSR로 서버에서 만들어지는 데이터가 변화하는 html 등)에 대한 요청이 들어올 때 응답. DB에 접근하여 콘텐츠를 가져오고 서버 측의 비즈니스 로직을 수행함(* API 서버로서도 역할함)
Web Server 사용 이유 (WAS 가 Web Server의 역할도 할 수 있는데, 둘을 분리하는 이유)
1. 업무 분담을 통해 WAS의 부담 감소
2. 보안에 유리
- 실제 DB에 접근하는 WAS 앞에 외부 요청을 받아서 이상한 요청(단기간에 너무 많은 요청-Ddos-)등이 왔을 때 막아주는 거름망 역할
- WAS의 엔드포인트를 브라우저가 몰라도 됨
3. 확장 및 로드밸런싱에 유리
- 트래픽이 몰릴 경우 WAS 개수만 늘리면 됨
- WS가 요청을 중개해서 보내므로 트래픽에 따라 자원이 남는 WAS로 요청을 보내는 로드밸런싱에 용이함
4. 캐싱을 통한 성능 향상
'공부' 카테고리의 다른 글
| 문제 해결 기법에서 추상화란 (0) | 2026.03.08 |
|---|---|
| unity08 3d 게임 만들어보기 (0) | 2026.02.10 |
| unity07 다양한 환경의 기기에서 동작 일관화 시키기 (0) | 2026.02.10 |
| unity06 반복되는 오브젝트 / 애니메이션 만들기 (0) | 2026.02.10 |
| unity05 중력/충돌 (0) | 2026.02.10 |