공공 API CORS 에러. proxy 서버로 해결!

hotbreakb·2022년 6월 1일
1

south-korea-weather

목록 보기
2/5

백엔드도 없는데 왜 이런 에러가 나는 걸까? 허허... postman에서 GET을 하거나 브라우저 URL 창에 입력하면 잘 돌아가는데, 대체 왜 내가 만든 사이트에서만 안 돌아가는 건지 🤪

에러 해결을 위해 도전한 방법

  1. https://cors-anywhere.herokuapp.com를 요청API 주소 앞에 붙이기
    • 실패 💩
    • cors-anywhere를 남용하는 사람들이 많아서 막아뒀다는 글을 읽었다.
  2. cors-anywhere를 fork하여 heroku에 연결
  3. http-proxy-middleware 사용하기
    • 성공 🎉
    • localhost에서도 가능하다.

http-proxy-middleware 사용하는 법

  1. $ yarn add http-proxy-middleware
  2. src/setupProxy.js 만들기
    • typescript 프로젝트도 js로 만들어도 잘 돌아간다.
  3. 코드 추가
// setupProxy.js

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

module.exports = function (app) {
    app.use(
        createProxyMiddleware('/프로젝트에서 사용할 주소', {
            target: 'API요청할주소 예)공공API주소',
			pathRewrite: {
                '^/api': ''
            },
            changeOrigin: true
        })
    )
};
module.exports = function (app) {
    app.use(
        createProxyMiddleware('/api', {
            target: 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst',
            pathRewrite: {
                '^/api': ''
            },
            changeOrigin: true
        })
    )
};
  1. axios url 변경
  useEffect(() => {
    axios({
      method: "GET",
      params: {
        nx: 5,
        ny: 127,
        pageNo: 1,
        numOfRows: 10,
        dataType: "JSON",
        base_date: getKoreaTime().date,
        base_time: getBaseTime(getKoreaTime().hour),
      },
      url: `/api? --------------------------------------------> 여기 변경 serviceKey=${process.env.REACT_APP_WEATHER_API_KEY}`,
    }).then((res) => {
serviceKey를 params로 빼면 인식이 되지 않는다. 이유는 알 수 없다.

CORS는 뭘까?

CORS(Cross-Origin Resource Sharing)

CORS 에러는 백엔드에서 발생하는 에러가 아니라, 브라우저에서 일어나는 문제다! 내 브라우저가 내가 만든 사이트를 믿지 못한다.

CORS가 왜 있을까?

브라우저의 토큰에 저장되어있는 개인정보를 유출하지 않기 위해 SOP(Same-Origin Policy)가 적용되어 있다. 동일출처정책은 말 그대로 출처가 같은 것만 허용해주는 것이다. 나의 사이트인 localhost:3000는 공공 API에서 허락해주지 않았기 때문에 에러가 나는 것이다.

어떻게 나의 개인정보가 유출될 수 있을까?

자동 로그인

브라우저의 토큰에 내 정보가 담겨있을 때, 이 토큰을 로그인했던 사이트에 요청할 때 실어 보내면, 쿠키를 보고 로그인되어있다고 판단한다.

나쁜 사례

  1. 악당 사이트👿를 눌러 실행한다.
  2. 로그인 정보가 담긴 사이트로 접속한다.
  3. 자동 로그인이 된다.
  4. 악당 사이트에서 다운받은 코드로 인해 내 토큰을 악당 사이트로 전달한다. 개인정보 유출🚨

이런 사례를 막기 위하여 브라우저에서 보호하고 있다. CORS를 허용해줄 주소를 명시해두면, 이 주소에서도 API를 호출할 수 있게 된다. 백엔드에서는 허락할 출처를 미리 명시해두면 된다.

서버의 답장 header에 지정된 Access-Control-Allow-Origin를 실어서 보낸다. 요청한 나의 사이트가 이 안에 있으면 안전한 요청으로 간주하고 응답 데이터를 받아올 수 있다. (GET, POST)

해결 방법

기존에는 브라우저에서 서버로 직접 요청했는데, 이때 CORS 에러가 뜬다.
proxy 서버를 사용하면 브라우저 → proxy 서버 → 공공 API로 요청, 즉 서버가 서버에게 요청하기 때문에 CORS 에러가 나지 않는다.

profile
글쟁이 프론트 개발자, 헬렌입니다.

0개의 댓글