Skip to main content

CORS (Cross-Origin Resource Sharing)

CORS(교차 출처 리소스 공유) 는 브라우저가 자신의 출처(Origin)가 아닌 다른 출처(Origin)의 리소스에 접근하는 것을 통제하는 보안 정책입니다.

쉽게 말해, "내 사이트(my-shop.com)에서 허락받지 않은 남의 사이트(api.kicc.co.kr)의 데이터를 함부로 가져오지 못하게 막는 브라우저의 방어막" 입니다.


🛑 왜 발생하나요? (SOP 정책)

웹 브라우저는 기본적으로 SOP (Same-Origin Policy, 동일 출처 정책) 를 따릅니다. 즉, 프로토콜, 호스트, 포트가 모두 같아야만 안전하다고 판단합니다.

  • 허용: http://localhost:3000 ➡️ http://localhost:3000/api/data (출처 같음)
  • 차단: http://localhost:3000 ➡️ https://api.kicc.co.kr/approve (도메인이 다름)

결제 연동 시, 개발 로컬 환경(localhost)에서 PG사 서버로 직접 API를 요청하면 브라우저는 이를 보안 위협으로 간주하고 빨간색 에러 메시지를 띄웁니다.

🚨 Access to fetch at '...' has been blocked by CORS policy


🛠️ 결제 연동 시 해결 방법

결제 API 연동 중 CORS 에러를 만났다면, 브라우저 설정을 끄는 것이 아니라 올바른 연동 구조를 잡아야 합니다.

1. 백엔드를 통한 호출 (Server-to-Server) [권장]

대부분의 PG(결제) 승인 API는 보안상 Secret Key를 사용합니다. 이 키는 브라우저에 노출되면 안 되므로, 반드시 백엔드 서버에서 호출해야 합니다. 서버 간 통신(Server-to-Server)에는 CORS 정책이 적용되지 않습니다.

2. 개발 환경에서 Proxy 설정 (Localhost)

프론트엔드 개발 단계에서 임시로 테스트가 필요하다면, Proxy(중계) 서버 설정을 통해 브라우저를 속일 수 있습니다.

React (Vite) 예시: vite.config.js 파일에 설정을 추가하여, 마치 내 서버(localhost)로 요청하는 것처럼 위장합니다.

// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: '[https://sandbox-api.kicc.co.kr](https://sandbox-api.kicc.co.kr)', // 실제 API 주소
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});
  • 요청: fetch('/api/payment/approve')
  • 실제 동작: Vite 서버가 https://sandbox-api.kicc.co.kr/payment/approve로 대신 요청

❓ 자주 묻는 질문

Q. KICC 서버에서 Access-Control-Allow-Origin: * 헤더를 내려주면 안 되나요?

A. 보안상 불가능합니다. 만약 모든 곳(*)에서 호출을 허용하면, 해커가 만든 피싱 사이트에서도 KICC API를 마음대로 호출할 수 있게 됩니다. 금융 데이터 보호를 위해 결제 API는 엄격한 CORS 정책을 유지합니다.

Q. Postman에서는 잘 되는데 브라우저에서만 안 돼요.

A. 정상입니다. CORS는 '브라우저' 가 지키는 보안 정책입니다. Postman, cURL, 백엔드 서버(Java, Node.js 등)는 브라우저가 아니므로 CORS의 제약을 받지 않고 통신이 가능합니다.