공공데이터 API CORS 이슈 해결을 위해 직접 프록시 서버 구축하기

윤영훈·2021년 8월 9일
1

프록시 서버 개발 이유 ❔

리액트를 사용한 프로젝트에서 공공데이터 API를 사용하려고 했지만 CORS 이슈로 인하여 클라이언트에서 바로 접근할 수 없었다. CORS는 브라우저에 관련된 정책이기 때문에 서버 간 통신을 할 때는 이 정책이 적용되지 않기 때문에 프록시 서버를 Express를 사용하여 구축 하기로 하였다.

📌 프록시 서버 정리

프록시 서버란 클라이언트가 자신을 거쳐 다른 네트워크에 접속할 수 있도록 중간에서 대리해주는 서버를 말합니다. 서버와 클라이언트 사이에서 대리로 통신을 수행해주는 것을 프록시라고 하고 그 기능을 하는 서버를 프록시 서버라고 부르게 되는 것 입니다.

📌 CORS ( 교차 출처 리소스 공유) 정리

CORS : 서로 다른 출처(Origin) 간에 리소스를 전달하는 방식을 제어하는 체제

보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한합니다. 예를 들어, XMLHttpRequest와 Fetch API는 동일 출처 정책을 따릅니다. 즉, 이 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 합니다. - 출처

예시 코드 )

사용한 라이브러리

  • request : 비동기 통신을 위해 사용하였습니다.
  • xml-js : 제가 사용한 API는 XML 데이터로 전송하기 때문에 JSON 객체로 바꿔주기 위하여 사용하였습니다.
const express = require('express');
const app = express();
const request = require('request-promise-native');
const convert = require('xml-js');

// env 파일 사용 설정
require('dotenv').config();

app.get('/hospital/:siDoCd/:siGunGuCd', async (req, res) => {
  let siDoCd = req.params.siDoCd;
  let siGunGuCd = req.params.siGunGuCd;
  let url = `http://apis.data.go.kr/openapi/service/rest/HmcSearchService/getRegnHmcList?serviceKey=${process.env.API_KEY}&siDoCd=${siDoCd}&siGunGuCd=${siGunGuCd}`;
  try {
    let response = await request(url);

    response = convert.xml2js(response, {
      compact: true,
      spaces: 4,
      ignoreDoctype: true,
    });
    res.json(response.response.body.items);
  } catch (e) {
    console.log(e);
    res.send('error!');
  }
});

app.get('/pharmacy/:yPos/:xPos', async (req, res) => {
  let xPos = req.params.xPos;
  let yPos = req.params.yPos;
  let url = `http://apis.data.go.kr/B552657/ErmctInsttInfoInqireService/getParmacyLcinfoInqire?serviceKey=${process.env.API_KEY}&WGS84_LON=${yPos}&WGS84_LAT=${xPos}`;
  try {
    let response = await request(url);

    response = convert.xml2js(response, {
      compact: true,
      spaces: 4,
      ignoreDoctype: true,
    });
    res.json(response.response.body.items);
  } catch (e) {
    console.log(e);
    res.send('error!');
  }
});

module.exports = app;

2개의 댓글

comment-user-thumbnail
2021년 8월 10일

좋은 정보 감사합니다 ㅎㅎ

1개의 답글