온라인의 IT,API,PYTHON 분위기를 보여주는 거리 풍경

CORS란 무엇이며 API 호출이 차단되는 이유는?

CORS는 브라우저가 서로 다른 출처의 웹 서버와 통신할 때 적용하는 보안 정책입니다. API 호출이 차단되는 원리와 해결 방법을 기초부터 알아봅니다.

온라인의 IT,API,PYTHON 분위기를 보여주는 거리 풍경

CORS란 무엇인가요?

CORS(Cross-Origin Resource Sharing)는 ‘교차 출처 리소스 공유’라는 뜻입니다. 웹 브라우저에서 실행되는 JavaScript가 현재 웹 페이지와 다른 출처(origin)의 서버에 API를 요청할 때, 해당 요청을 허용할지 판단하는 보안 규칙입니다.

예를 들어 웹 페이지 주소가 `https://frontend.example.com`이고 API 주소가 `https://api.example.com/users`라면, 두 주소는 호스트명이 다르므로 서로 다른 출처입니다. 이때 브라우저는 API 서버가 명시적으로 허용했다는 응답을 보내지 않으면 JavaScript가 응답 내용을 읽지 못하게 차단합니다.

여기서 출처는 보통 프로토콜, 호스트, 포트의 조합으로 판단합니다. `http://example.com`과 `https://example.com`은 프로토콜이 다르고, `http://localhost:3000`과 `http://localhost:8000`은 포트가 달라 서로 다른 출처입니다.

왜 API 호출이 차단될까요?

CORS는 동일 출처 정책(Same-Origin Policy)에서 출발합니다. 동일 출처 정책은 한 웹사이트의 스크립트가 사용자의 로그인 정보나 쿠키를 이용해 다른 사이트의 민감한 정보를 마음대로 읽지 못하도록 막는 브라우저 보안 원리입니다.

만약 이 제한이 없다면, 사용자가 어떤 서비스에 로그인한 상태에서 악성 웹사이트를 방문했을 때 그 사이트의 JavaScript가 사용자를 대신해 다른 서비스의 데이터를 요청하고 응답을 읽으려 할 수 있습니다. CORS는 API 서버가 ‘이 출처에서 오는 요청은 허용한다’고 알려준 경우에만 브라우저가 응답을 웹 페이지에 전달하도록 합니다.

중요한 점은 CORS가 서버 간 통신 자체를 막는 기능은 아니라는 것입니다. Python의 `requests` 라이브러리, 서버 측 Node.js 코드, Postman 같은 도구는 브라우저의 동일 출처 정책을 적용받지 않습니다. 따라서 Postman에서는 정상인데 브라우저의 `fetch()`에서는 오류가 나는 상황이 자주 발생합니다.

CORS 오류 메시지는 어떻게 이해해야 하나요?

브라우저 개발자 도구의 Console에서 다음과 비슷한 메시지를 볼 수 있습니다.

`No 'Access-Control-Allow-Origin' header is present on the requested resource.`

이는 API 서버 응답에 `Access-Control-Allow-Origin` 헤더가 없거나, 요청을 보낸 웹 페이지의 출처가 허용 목록에 없다는 의미입니다. 예를 들어 프론트엔드가 `http://localhost:3000`에서 실행된다면 API 서버는 다음과 같이 응답해야 할 수 있습니다.

`Access-Control-Allow-Origin: http://localhost:3000`

모든 출처를 허용하는 `Access-Control-Allow-Origin: *`도 가능하지만, 로그인 쿠키나 인증 정보를 사용하는 API에는 신중해야 합니다. 특히 `credentials`를 포함하는 요청에서는 와일드카드(`*`)를 사용할 수 없고, 허용할 정확한 출처를 지정해야 합니다.

프리플라이트 요청은 무엇인가요?

일부 요청은 실제 API 요청 전에 브라우저가 `OPTIONS` 메서드로 사전 확인 요청을 보냅니다. 이를 프리플라이트(preflight) 요청이라고 합니다. 예를 들어 `PUT`, `PATCH`, `DELETE` 메서드를 사용하거나, `Authorization` 같은 특정 헤더를 추가하거나, JSON 형식의 요청을 보낼 때 프리플라이트가 발생할 수 있습니다.

API 서버는 이 `OPTIONS` 요청에 대해 허용할 메서드와 헤더를 응답해야 합니다. 대표적으로 다음 헤더가 사용됩니다.

- `Access-Control-Allow-Origin`: 허용할 웹 페이지 출처
- `Access-Control-Allow-Methods`: 허용할 HTTP 메서드
- `Access-Control-Allow-Headers`: 허용할 요청 헤더
- `Access-Control-Allow-Credentials`: 쿠키·인증 정보 포함 요청 허용 여부

프리플라이트가 실패하면 실제 `POST`나 `DELETE` 요청은 전송되지 않을 수 있습니다. 따라서 API 서버에서 `OPTIONS` 요청을 처리하도록 설정하는 것이 필요합니다.

CORS는 어디에서 해결해야 하나요?

원칙적으로 CORS는 API 서버에서 설정해야 합니다. 프론트엔드 코드에서 `mode: 'no-cors'`를 설정해 해결하려는 시도는 대부분 올바른 방법이 아닙니다. 이 옵션은 응답 내용을 JavaScript에서 읽을 수 없는 opaque response를 만들 수 있어 일반적인 API 활용에 적합하지 않습니다.

Python의 FastAPI에서는 `CORSMiddleware`를 사용해 허용 출처, 메서드, 헤더를 설정할 수 있습니다. Flask는 보통 `flask-cors` 확장 도구로 설정합니다. 개발 환경에서는 `http://localhost:3000`처럼 필요한 로컬 주소를 허용하고, 운영 환경에서는 실제 서비스 도메인만 제한적으로 등록하는 방식이 안전합니다.

학습방법으로는 먼저 브라우저 개발자 도구의 Network 탭에서 요청 URL, Origin 요청 헤더, OPTIONS 요청 여부, 응답의 CORS 헤더를 확인해 보세요. 그다음 프론트엔드 주소와 서버의 허용 출처 설정이 정확히 일치하는지 비교하면 문제 원리를 더 쉽게 파악할 수 있습니다.

자주 묻는 질문

CORS 오류는 API 서버가 고장 났다는 뜻인가요?

반드시 그렇지는 않습니다. API가 정상 응답을 반환해도 브라우저가 CORS 정책 때문에 해당 응답을 JavaScript에 전달하지 않을 수 있습니다. Postman으로 요청이 성공하고 브라우저에서만 실패한다면 CORS 설정을 우선 확인하세요.

개발 중에는 모든 출처를 허용해도 되나요?

간단한 실습에서는 가능할 수 있지만, 운영 서비스에서는 권장되지 않습니다. 특히 인증 쿠키나 사용자 정보가 포함되는 API라면 필요한 프론트엔드 도메인만 명시적으로 허용해야 합니다.

프론트엔드에서 CORS를 해결할 수 있나요?

근본적인 해결은 API 서버의 응답 헤더 설정입니다. 개발 환경에서는 프론트엔드 개발 서버의 프록시 기능을 사용해 우회할 수 있지만, 실제 서버의 CORS 정책을 대체하는 방법은 아닙니다.

관련 가이드

웹 API 기초

웹 API 보안 기초: API 키를 안전하게 관리하는 법

API 키의 역할과 한계를 이해하고, 코드·환경 변수·서버 설정에서 키를 안전하게 관리하는 기본 원칙을 살펴봅니다.

API 서버 입문

초보자를 위한 API 서버 배포 방법 비교

로컬에서 만든 Python API를 실제 사용자가 접근할 수 있게 만드는 배포의 원리를 이해하고, PaaS·가상 서버·컨테이너 기반 배포 방식을 기초 관점에서 비교합니다.

API 서버 입문

Python Flask로 첫 API 서버 만들기

Flask를 이용해 요청을 받고 JSON으로 응답하는 가장 기본적인 API 서버를 만들어 봅니다. 설치부터 실행, 라우팅, 상태 코드까지 초보자가 알아야 할 원리를 단계별로 설명합니다.

Python API 실습

Python API 호출 오류와 해결 방법 FAQ

Python에서 API를 호출할 때 자주 만나는 오류를 상태 코드, 요청 형식, 인증, 네트워크 관점에서 정리한 초보자용 FAQ입니다.

Python API 실습

Python으로 API 호출하기: requests 사용법

Python의 requests 라이브러리로 웹 API에 GET·POST 요청을 보내고, 응답을 안전하게 처리하는 기초 방법을 설명합니다.

API 입문

REST API 요청과 응답 구조 이해하기

REST API에서 클라이언트가 서버에 요청을 보내고, 서버가 응답을 돌려주는 기본 흐름을 HTTP 메서드, URL, 헤더, 본문, 상태 코드 중심으로 설명합니다.

API 입문

API란 무엇인가요? 초보자를 위한 완전 가이드

API의 뜻과 작동 원리, 웹 API 요청과 응답의 구조, Python으로 시작하는 기초 학습 방법을 초보자 눈높이에서 설명합니다.

IT 기초

클라이언트와 서버의 차이 쉽게 이해하기

웹과 API의 기본이 되는 클라이언트와 서버의 역할, 요청과 응답이 오가는 원리를 초보자도 이해하기 쉽게 설명합니다.

IT 기초

API를 배우기 전 알아야 할 IT 기초 용어

API 학습을 시작하기 전에 알아두면 좋은 웹, 서버, 네트워크, 데이터 관련 핵심 용어와 학습 방법을 정리합니다.