에러해결

CORS 오류(“Blocked by CORS policy”) 해결 가이드: 원인 → 체크리스트 → 실전 설정 예시

zumsim 2026. 2. 3. 00:11
728x90
반응형

메타 설명(SEO용): CORS 오류가 왜 생기는지, 프리플라이트(OPTIONS)부터 Access-Control-Allow-Origin 설정까지 한 번에 정리했습니다. Spring/Node/Nginx 예시 포함.


목차

CORS가 뭔데 이렇게 자주 터질까?

CORS(Cross-Origin Resource Sharing)는 브라우저가 “다른 출처(도메인/포트/프로토콜)”로 요청할 때, 서버가 허용할지 말지를 HTTP 헤더로 명시하는 규칙입니다. 특히 JSON API 호출이 많아진 프론트/백 분리 구조에서 자주 마주쳐요.

가장 흔한 증상 5가지(에러 문구 그대로)

  • Blocked by CORS policy: No 'Access-Control-Allow-Origin' header…
  • Response to preflight request doesn't pass access control check…
  • The value of the 'Access-Control-Allow-Origin' header must not be '*' when credentials…
  • Request header field xxx is not allowed by Access-Control-Allow-Headers…
  • CORS preflight channel did not succeed…

해결 전 체크리스트(이거부터 보면 10분컷)

  1. 요청 출처(origin) 확인: https/http, 포트, 서브도메인까지 정확히
  2. 쿠키/세션(credentials) 쓰는지 확인: withCredentials 또는 credentials: 'include'
  3. 프리플라이트(OPTIONS)가 막혔는지 확인: 서버/프록시에서 OPTIONS 허용 필요
  4. 허용 헤더 확인: Authorization, Content-Type, 커스텀 헤더 등
  5. 리다이렉트 확인: 301/302가 걸리면 CORS가 더 꼬일 수 있어요

해결 방법 5가지(권장 순서)

1) 서버에서 ‘정확한 Origin’만 허용하기

가장 안전하고, 운영 환경에서도 유지보수하기 좋습니다.

2) credentials를 쓰면 “*” 금지

쿠키/세션을 포함하는 요청은 Access-Control-Allow-Origin: *로 해결이 안 됩니다. 반드시 명시적인 Origin을 넣어야 해요.

3) OPTIONS(프리플라이트) 응답을 200으로 처리

프록시(Nginx)나 WAS에서 OPTIONS가 403/404면 프론트는 바로 막힙니다.

4) 개발 단계에서는 ‘프록시’로 우회(운영에선 비추)

로컬 개발 중에만 프론트 devServer proxy를 쓰면 빠르게 해결됩니다.

5) 헤더/메서드/노출 헤더까지 완성하기

특히 Authorization, Content-Type, X-Requested-With 같은 것들로 많이 터져요.

Spring/Express/Nginx 예시

✅ Spring (Spring MVC / Spring Boot 공통 개념)

// 예시: 특정 Origin만 허용 + 메서드/헤더 지정 (개념 예시)
registry.addMapping("/api/**")
        .allowedOrigins("https://example.com")
        .allowedMethods("GET","POST","PUT","DELETE","OPTIONS")
        .allowedHeaders("Authorization","Content-Type")
        .allowCredentials(true);

✅ Express(Node.js) - cors 미들웨어

import cors from "cors";
app.use(cors({
  origin: ["https://example.com"],
  credentials: true,
  methods: ["GET","POST","PUT","DELETE","OPTIONS"],
  allowedHeaders: ["Authorization","Content-Type"],
}));

✅ Nginx (프리플라이트가 막힐 때)

# 개념 예시: OPTIONS 요청에 대해 204/200 응답 + 필요한 헤더 추가
if ($request_method = OPTIONS) {
  add_header Access-Control-Allow-Origin https://example.com;
  add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
  add_header Access-Control-Allow-Headers "Authorization, Content-Type";
  add_header Access-Control-Allow-Credentials true;
  return 204;
}

FAQ

Q1. “서버는 정상인데 브라우저만 실패” 왜 그래요?

Postman/curl은 브라우저 CORS 정책을 강제하지 않아서, “브라우저에서만” 실패하는 게 정상 패턴입니다.

Q2. 운영에서 그냥 CORS 끄면 안 되나요?

보안 정책을 무력화할 수 있어요. 운영에서는 “허용 Origin을 최소화”하는 방향이 권장됩니다.


 

728x90
반응형