Vite & axios CORS 해결하기

Jemin·2023년 5월 21일
0

트러블슈팅

목록 보기
4/11
post-thumbnail

최근 과제테스트에서 API 요청으로 데이터를 받아와야 했는데 API KEY와 쿠키 허용까지 했는데도 CORS 에러가 발생해서 문제를 해결하지 못하고 제출한 경험이 있다. 다음에도 같은 상황에서 해결하지 못하면 안되기 때문에 이번에 해결방법을 정리하고자 한다.

SOP(Same Origin Policy, 동일 출처 정책)

자바스크립트 엔진 표준 스펙의 보안 규칙 중, 하나의 출처(Origin)에서 로드된 자원(문서나 스크립트)이 일치하지 않는 자원과 상호작용 하지 못하도록 요청 발생을 제한하는 정책이다.

즉, http://localhost:8000http://localhost:8000/posts는 같은 출처라서 상호작용이 가능하지만, http://google.com에서 http://localhost:8000을 호출하면 SOP에 위배된다. 그렇다면 동일 출처의 기준은 무엇일까?

동일 출처의 기준

 http://example.com:8042/over/there?name=ferret&page=1#nose
 \__/  \__________/\___/ \________/ \________________/\___/
   |         |       |       |               |          |
protocol    host    port    path       query string  Fragment

protocol, host, port가 같아야 동일한 출처다.

브라우저 입장에서는 string으로 비교하기 때문에 localhost와 127.0.0.1을 다른 출처라고 판단하기에 주의해야 한다.

CORS(Cross Origin Resource Sharing, 교차 출처 자원 공유)

CORS는 다른 출처의 자원의 공유를 가능하게 만들어준다. 또한, 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 어플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.

CORS 에러는 브라우저가 뿜어낸다. Server와 Server간에는 CORS 에러가 발생하지 않는다.

CORS 해결하기

CORS에러는 Client에서 Server(api)에 접근하여 resource를 가져올 때, 출처가 같지 않으면 브라우저에서 발생시킨다. CORS는 Server에서 해결할 수도 있고, Client에서 해결할 수도 있다.

Server에서 해결하는 방법은 CORS 미들웨어를 사용하거나, Server에서 Access-access-control-allow-origin 헤더를 세팅(접근 허용)해주면 해결할 수 있다. 그런데 만약, Server를 수정할 수 없거나 Open API를 사용한다면 Client에서 처리할 수 밖에 없을 것이다. Client에서 CORS를 해결하는 방법은 Proxy Server를 이용하는 것이다.

Proxy Server란, 다른 네트워크 서비스에 간접적으로 접속할 수 있게 도와주는 Server를 가리킨다. 즉, Client에서 CORS 에러를 핸들링 하는 것은 서버로 가기 전에 Proxy Server를 거쳐서 출처를 response와 같게 수정하고, Server에 접근하도록 하는 것이다.

React에서 CORS 해결하기

CRA에서는 http-proxy-middleware라는 라이브러리를 사용해서 해결하거나, Proxy Server에 대한 파일을 생성해서 해결해주는 것 같은데, 나는 Vite를 좋아하고 자주 사용하기 때문에 Vite로 생성된 프로젝트에서 해결하는 방법을 찾았다.

일단 공식문서에서 쉽게 찾아볼 수 있다.

공식 문서 링크: 서버 옵션 [Vite]

Vite는 외부 라이브러리 설치없이 프로젝트 생성시 같이 생성되는 vite.config.js파일내에서 해결할 수 있다.

Vite에서 제공하는 http://jsonplaceholder.typicode.com 주소를 통해 /users를 엔드포인트로 설정해서 데이터를 가져오는 코드를 작성해보았다.

// api.js
import axios from "axios";

export const getData = async () => {
  const response = await axios.get(
    "https://jsonplaceholder.typicode.com/users"
  );
  return response.data;
};

서버쪽에서 이미 Reverse Proxy가 설정되어 있는지 정상적으로 데이터가 받아와지는데, 그래도 일단 Proxy Server를 설정해보자.

vite.config.js 파일에서 간단하게 수정해주면 된다.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      "/api": {
        target: "https://jsonplaceholder.typicode.com",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ""),
      },
    },
  },
});

위 코드처럼 수정하면 API 요청시 "/api" 앞 부분인 origin을 target에 설정되어 있는 부분으로 정규표현식을 통해 바꿔준다는 것을 의미한다.

이제 API를 요청하는 부분의 주소를 수정해주면 된다.

import axios from "axios";

export const getData = async () => {
  const response = await axios.get("/api/users");
  return response.data;
};

위 처럼 데이터가 정상적으로 받아와지는 것을 확인할 수 있다.

profile
경험은 일어난 무엇이 아니라, 그 일어난 일로 무엇을 하느냐이다.

0개의 댓글