seungjun.dev

프록시와 Vite 환경에서 CORS 문제 회피하는 법

프록시 개념과 Vite 환경에서 이를 적용해서 CORS 문제 회피하는 법

프록시

  • CORS 문제를 해결하는 아주 Fun & Cool & Sexy한 방법
  • 동일 출처 정책(SOP)를 우회하기 위해 내 서버를 일종의 대리인으로 내세우는 것

이 글을 읽으려면 CORS 문제에 대한 충분한 이해가 필요합니다. 여기에서 CORS와 관련된 개념과 Node.js에서 로우 레벨로 구현된 예제를 확인해보세요!

왜 프록시가 필요한가?

CORS 에러는 브라우저가 다른 출처로의 요청을 보안상의 이유로 차단하기 때문에 발생한다.

서버가 Access-Control-Allow-Origin 헤더로 응답해주지 않으면, 브라우저는 데이터를 받더라도 무시하고 에러를 띄운다.

그러나 이 정책은 브라우저에만 해당된다. 서버와 서버 간의 통신에는 적용되지 않는다.

프록시는 바로 이 점을 이용한다.

프록시의 동작 원리

CORS 문제를 겪는 일반적인 상황과 프록시를 사용한 해결 방법을 비교해 본다.

문제 상황: 직접 요청 (CORS 에러 발생)

  1. 브라우저에서 외부 API 서버로 직접 데이터 요청
  2. 외부 API 서버가 Access-Control-Allow-Origin 헤더를 응답에 포함해주지 않음
  3. 브라우저는 이 응답을 받고 보안 위협으로 간주하여 CORS 에러 발생

해결 방법: 프록시 서버 경유

  1. 브라우저는 같은 출처인 내 프록시 서버로 데이터 요청
    • 같은 출처끼리의 통신이므로 CORS 에러가 발생하지 않는다
  2. 내 프록시 서버는 브라우저의 요청을 받아서, 대신 외부 API 서버로 데이터를 요청
    • 서버와 서버 간의 통신이므로, CORS 정책이 적용되지 않아 자유로운 통신이 가능하다.
  3. 외부 API 서버는 요청받은 데이터를 내 프록시 서버에게 응답
  4. 내 프록시 서버는 외부 API로부터 받은 데이터를 그대로 브라우저에게 전달

브라우저 입장에서는 그냥 내 서버와 통신했을 뿐인데, 실제로는 외부 API의 데이터를 받아온 셈이다.

프록시 설정 트러블 슈팅 사례

문제 상황

발생한 현상

  • 백엔드 서버가 3000 포트에서 정상 실행 중
  • http://localhost:3000/index로 HTML 페이지는 정상 로드
  • HTML 내의 이미지들이 5173 포트로 요청되어 이미지가 불러와지지 않는 오류 발생

개발자 도구 로그

문제 원인 분석

1. 서버 구조

  • 백엔드 서버: 3000 포트에서 실행
    • /index 경로: HTML 페이지 제공
    • /static/ 경로: 정적 파일(이미지) 제공
  • 프론트엔드 개발 서버: Vite가 5173 포트에서 실행

2. 요청 흐름 문제

  1. 브라우저가 http://localhost:5173에서 개발 서버에 접근
  2. Vite 프록시를 통해 /index 요청이 3000 포트로 전달 → HTML 로드 성공
  3. 브라우저가 HTML 파싱 중 <img src="/static/logo.svg"> 발견
  4. 문제: /static/ 경로에 대한 프록시 설정이 없어서 5173 포트에서 파일을 찾으려 시도
  5. 5173 포트에는 해당 이미지가 없어서 404 에러 발생

3. 근본 원인

Vite 설정에서 /static/ 경로에 대한 프록시 설정 누락

기존 vite.config.ts:

export default defineConfig({
  server: {
    proxy: {
      '/index': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
      // ❌ /static/ 프록시 설정 누락
    },
  },
});

해결 방법

Vite 프록시 설정 수정

frontend/vite.config.ts/static/ 프록시 추가:

export default defineConfig({
  server: {
    proxy: {
      '/index': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
      // ✅ 정적 파일 프록시 추가
      '/static': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
    },
  },
});

학습 포인트

1. 개발 환경에서의 프록시 역할

  • 프론트엔드 개발 서버와 백엔드 API 서버가 다른 포트에서 실행될 때
  • 프록시를 통해 특정 경로의 요청을 백엔드로 전달
  • 모든 필요한 경로에 대해 프록시 설정이 필요

2. 디버깅 방법

  • 개발자 도구 Network 탭에서 실제 요청 URL 확인
  • 요청이 어느 포트로 가는지 체크
  • 프록시 설정과 실제 요청 경로 매칭 확인

관련 기술

Vite 프록시 설정 옵션

  • target: 프록시할 대상 서버
  • changeOrigin: Origin 헤더를 대상 서버로 변경
  • rewrite: 경로 재작성 (필요시)
  • secure: HTTPS 인증서 검증 (개발시 false)

CORS와의 차이점

  • CORS: 서로 다른 도메인 간의 리소스 공유 정책
  • 프록시: 개발 환경에서 요청을 다른 서버로 전달하는 메커니즘
  • 이 문제는 CORS 문제가 아닌 프록시 설정 누락 문제였음