리액트 CORS 에러 해결 기록

yunjeong·2022년 9월 16일
3

Today I Learned

목록 보기
4/4

웹개발자라면 피해갈 수 없다는 CORS 에러.. 드디어 나도 맞닥뜨리고 말았다. 네이버 영화검색 API를 적용하며 에러를 발견했고, 삽질했던 기록을 남겨두려한다.


CORS

CORS는 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)이며, 다른 출처의 자원에 접근할 수 있는지 권한을 검사하는 관문이기도 하다.

~~ has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

^^.. 많이들 보셨을 에러메시지. 당신은 CORS 정책에 의해 차단되었으며 요청한 리소스에 ACAO 헤더가 없다. 돌아가시오~!

메시지를 보면 Access-Control-Allow-Origin 헤더를 넣으면 될 것 같은데, 나는 네이버의 API를 사용하려고 했으므로 직접 서버 코드를 수정할 수 없었다. 해결을 위해 구글링을 해보니 package.json에 프록시 관련 코드를 넣거나 라이브러리를 통해 프록시를 구축하는 등의 방법이 있었다.

프록시 설정하기

package.json에 proxy 추가하기?


package.json에 API 주소를 써넣는 방법으로 우회할 수 있다고 했지만 에러는 해결되지 않았다. 게다가 이는 개발 단계에서만 유효하여 배포 후에는 먹히지 않는다고 하며, 하나의 주소만 쓸 수 있어 다양한 처리가 불가능한 단점이 있었다.

라이브러리를 사용해 proxy 설정 완료하기!

그래서 라이브러리를 사용해 설정하기로 했다.
npm i http-proxy-middleware

설치 후 ./src 폴더에 setupProxy.js 파일을 만든 후 아래 내용을 작성해주었다.

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
  app.use(
    "/naver_api",
    createProxyMiddleware({
       target: "https://openapi.naver.com",
       pathRewrite: {
       //naver_api로 시작되는 url을 자동 인식 -> 프록시 처리, /naver_api는 ""로 대체됨
         "^/naver_api": "",
       },
      changeOrigin: true,
    })
  );
};

이렇게 코드를 작성해두면 브라우저에서 naver_api로 시작되는 요청을 보낼 때 설정된 proxy에 의해 변환되어 타겟 url로 보내진다.
다만.. 문제가 생겼다. 이 코드는 대거 수정되게 된다..

프록시 설정 완료! 그런데..

값 리턴이 왜 안돼?!

모두 잘 설정했다고 생각했고, CORS 에러도 해결되었다. 그런데.. API서버에 요청한 값이 리턴되지 않았다.


개발자 도구 - 네트워크에서 나의 요청을 확인해봤다. 이상하다? 상태코드 200으로 잘 뜨는데 왜 로그를 찍어보면 데이터가 계속 undefined로 나오는 거지? 😱

error_code: "052", message: "naver_api : partner does not exists. (등록된 파트너가 없습니다.)"

여기서 미리보기를 확인한 결과.. 에러를 자세히보니 메시지에 "naver_api"가 눈에 띄었다.
부랴부랴 헤더로 돌아가 요청 URL을 확인하니, http://localhost:3000/naver_api/v1/search/movie.json?query=~~
구분하겠다고 썼던 naver_api가 rewrite처리 되지 않고 그대로 살아서 네이버 API의 요청 URL(https://openapi.naver.com/v1/search/movie.json) 과 다른 주소가 되어 버렸던 거였다.

해결

setupProxy.js를 아래처럼 수정하였다.

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
  app.use(
    "/v1",
    createProxyMiddleware({
       target: "https://openapi.naver.com",
      changeOrigin: true,
    })
  );
};

수정 후 axios.get 부분의 url도

const naverMovieSearch = axios.create({
  headers: {
    "X-Naver-Client-Id": `${keys.NAVER_CLIENT_ID}`,
    "X-Naver-Client-Secret": `${keys.NAVER_CLIENT_SECRET}`,
  },
});

export const movieSearch = (params) => {
  return naverMovieSearch.get("/v1/search/movie.json", { params });
};

이렇게 변경해주어 성공적으로 값을 받아올 수 있었다.


정리

  1. CORS 해결 위해 http-proxy-middleware 라이브러리 설치
  2. setupProxy.js 설정
  3. /v1으로 시작하는 url 요청이 프록시를 통과하여 자원에 접근 성공

라이브러리 설치 후 셋업 파일을 설정할 때 구글링으로 알아낸 코드를 그대로 복사 붙여넣기 해서 사용했었던 게 문제인 것 같다. 아무리 기본 틀이라고 해도 내 코드와 완벽히 맞아떨어지지 않을 수 있다는 걸 잊었다..😢 문서나 사용법을 숙지하는 것이 느닷없는 에러를 줄이는 길인 것 같다.

profile
거침없이 한 달음에!

0개의 댓글