TECH 으로 돌아가기
TECH HACKER NEWS 어제 6분 읽기 53 READS

CORS 에러, 사실 당신 서버가 막은 게 아니에요 — 오해를 풀어드립니다

CORS 에러, 사실 당신 서버가 막은 게 아니에요 — 오해를 풀어드립니다

무슨 일이냐면

웹 개발하다가 한 번도 안 만나본 사람이 없을 거예요. 콘솔에 빨갛게 뜨는 그 메시지. No 'Access-Control-Allow-Origin' header is present. 바로 CORS 에러죠. 많은 개발자가 이걸 보면 「내 서버가 보안 때문에 요청을 거부했구나」라고 생각하는데, 사실 이건 거의 정반대에 가까운 오해예요. 오래된 주제이긴 하지만 지금도 수많은 주니어가 똑같이 헷갈리는 부분이라, 한 번 제대로 짚고 가면 평생 도움이 돼요.

CORS가 뭐냐면 (그리고 뭐가 아니냐면)

먼저 알아야 할 건 '동일 출처 정책(Same-Origin Policy)'이에요. 브라우저엔 기본 규칙이 하나 있어요. 「A 사이트에서 실행된 자바스크립트는 B 사이트의 응답을 함부로 읽지 못한다.」 여기서 '출처(origin)'는 프로토콜(http/https) + 도메인 + 포트를 합친 거예요. 셋 중 하나만 달라도 다른 출처로 봐요.

왜 이런 규칙이 있냐면, 바로 여러분을 지키기 위해서예요. 만약 이 규칙이 없으면, 여러분이 은행 사이트에 로그인한 상태에서 악성 사이트에 들어갔을 때, 그 악성 사이트의 자바스크립트가 여러분의 쿠키를 이용해 은행 API를 호출하고 잔액 정보를 빼갈 수 있거든요. 동일 출처 정책이 이걸 막아줘요.

그런데 현실에선 출처가 다른 서버끼리 데이터를 주고받아야 할 때가 많죠. 프론트는 app.com, API는 api.com처럼요. 이때 「이 출처는 믿어도 돼, 응답 읽게 해줘」라고 빗장을 풀어주는 약속이 바로 CORS(Cross-Origin Resource Sharing)예요. 핵심은 이거예요: CORS는 보안을 추가하는 기능이 아니라, 브라우저가 기본으로 걸어둔 빗장을 선택적으로 푸는 장치라는 점.

가장 큰 오해: 「서버가 요청을 막았다」

여기서 결정적인 오해가 풀려요. CORS 에러가 떠도, 사실 그 요청은 대부분 여러분 서버까지 멀쩡히 도착해서 실행돼요. 데이터베이스도 건드리고 응답도 만들어서 돌려줘요. 그럼 뭐가 막힌 거냐면, 브라우저가 그 응답을 자바스크립트한테 '전달하기'를 거부하는 거예요. 즉 차단은 서버가 아니라 브라우저(사용자 쪽) 에서 일어나요.

이게 왜 중요하냐면, 「CORS 설정해뒀으니 내 API는 안전하다」는 착각을 깨주기 때문이에요. 만약 GET 한 방으로 상태가 바뀌는(예: 삭제되는) 엔드포인트가 있다면, CORS는 그걸 못 막아요. 요청 자체는 이미 들어가 버리니까요. 진짜 보안은 인증·인가·CSRF 토큰 같은 서버 쪽 장치로 해야지, CORS한테 맡기면 안 돼요.

프리플라이트(preflight)는 또 뭐냐면

조금 복잡한 요청(예: PUT/DELETE나 커스텀 헤더를 단 요청)을 보내려 하면, 브라우저가 본 요청을 보내기 전에 OPTIONS 메서드로 서버한테 먼저 물어봐요. 「나 이런 출처에서 이런 메서드로 요청하려는데 괜찮아?」 이걸 프리플라이트라고 해요. 서버가 Access-Control-Allow-Origin, Access-Control-Allow-Methods 같은 헤더로 「응 괜찮아」라고 답하면 그제야 진짜 요청이 나가요. 그래서 네트워크 탭에 똑같은 주소가 OPTIONS랑 실제 메서드로 두 번 찍히는 거예요.

그래서 어떻게 고치냐면

해결은 결국 서버가 올바른 응답 헤더를 보내주는 것 이에요. 프론트 코드를 아무리 고쳐도 안 풀려요. 서버에서 Access-Control-Allow-Origin: https://app.com 식으로 허용할 출처를 명시해주면 돼요. 한 가지 함정은, 와일드카드 *는 쿠키 같은 인증 정보(credentials)를 함께 보낼 땐 못 써요. 이땐 출처를 정확히 지정하고 Access-Control-Allow-Credentials: true를 같이 줘야 해요. 개발 단계에서 급하면 프록시를 두는 방법도 있고요.

정리

CORS는 '내 서버를 지키는 방패'가 아니라 '브라우저가 사용자 보호를 위해 걸어둔 빗장을 푸는 열쇠'예요. 그러니 에러가 떴을 때 「내가 뭘 잘못했지?」가 아니라 「서버 헤더를 어떻게 열어줄까?」로 생각하면 훨씬 빨리 풀려요. 여러분은 CORS 때문에 가장 오래 헤맸던 경험이 뭔가요?


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://fosterelli.co/developers-dont-understand-cors
SHARE
처리 중...