CORS Issue

heyj·2022년 3월 4일
0

wanted_PreOnboarding

목록 보기
2/7
post-thumbnail

도로명주소 공공api를 이용하는 과제가 주어졌습니다.

도로명주소 api
https://www.juso.go.kr/addrlink/devAddrLinkRequestGuide.do?menu=roadApi

주소검색API는은 2가지로, 팝업창이 열리고 주소검색을 할 수 있도로 하는 팝업 API와
곧장 검색을 할 수 있는 검색API가 있었습니다.
만들어둔 ui에서 직접 검색이 되도록 하는 방안으로 해야해서 검색API를 이용했습니다.

1. CORS Issue

검색은 키워드, api key에 더해 타입, 받아올 결과 수 등을 넣어줘야 했기 때문에 post방식을 이용했습니다.

const data = {
  keyword: keyword,
  confmKey: process.env.REACT_APP_API_KEY,
  resultType: 'json',
  countPerPage: 100,
  currentPage: 1,
};

await Axios.post(`https://www.juso.go.kr/addrlink/addrLinkApi.do`, data)
  .then((res) => {
  if (res.data.results.juso.length < 1) {
    setNoSearchResult(true);
  }
  setSearchResult(res.data.results.juso);
})
  .catch((err) => console.log(err));

요청을 날리는 순간

개발할 때 안 보이면 서운한(?) error 메세지를 만났습니다.
CORS 정책 때문에 요청이 막혔다는 얘기...

2. CORS?

대부분의 웹 브라우저는 Same Origin Policy(SOP)라는 보안 정책을 준수합니다. 내가 접속한 사이트(Origin)에서 다른 Origin에 요청한 것을 기본적으로 제한해서 어느정도 공격 등 보안 이슈를 해결하는 것입니다.

Origin은 프로토콜, 주소, 포트번호까지를 의미합니다.
ex) http://localhost:3000
출처 내 포트 번호는 생략이 가능한데, 이를 생략하면 HTTP 방식은 80을, HTTPS방식은 443을 이용합니다. 다른 출처라고 하면 프로토콜(http, https), 주소(naver.com, google.com...), 포트번호(3000, 5000, 80, 433)이 다르다는 것입니다.

어떻게 고칠 수 있을지 온갖 실험을 해봤습니다.

3. 해결책(?!)

  • 저는 요청만 가능하고 서버를 제어할 수 있는 상황이 아니기 때문에, Access-Control-Allow-Origin를 설정 방법은 이용할 수 없었습니다.

    만약 Access-Control-Allow-Origin 설정이 가능하다면,
    허용할 Origin을 Access-Control-Allow-Origin 응답 헤더에 넣어주면 됩니다.
    모든 사이트를 허용하는 경우 - Access-Control-Allow-Origin: *
    특정한 사이트만 허용하는 경우: Access-Control-Allow-Origin: https://www.naver.com/

  • 서버를 구축하기에는 시간이 부족했습니다..ㅠㅠ 다른 방법을 찾기로..

1. 다른 사람이 만든 proxy 서버 이용하기

이미 길을 먼저 밟으신 선배님들께서 유용한 정보들을 블로그에 많이 남겨두셨습니다.(만세)
다른 사람이 만든 proxy server를 이용해 HTTP응답 해더의 Access-Control-Allow-Origin를 설정 방법을 이용했습니다.

https://cors-anywhere.herokuapp.com

이 주소를 url앞에만 넣어주면 됩니다. 이렇게 하면 중간에 요청을 가로채 HTTP 응답 헤더에 Access-Control-Allow-Origin: * 로 설정해 응답한다고 합니다.

2. 로컬 환경일 경우 한정, http-proxy-middleware 라이브러리를 사용

예전 프로젝트를 진행할 때 서버는 5000번 포트에서, 클라이언트는 3000번 포트에서 작업을 진행하고 있어서 역시 cors이슈가 발생했습니다.
이 때는 http-proxy-middleware 라이브러리를 사용해서 cors이슈를 해결했습니다.

src/setupProxy.js 파일을 만들어서 아래 내용을 넣어줍니다.
클라이언트에서 '/api'로 요청이 들어오면 target의 주소로 요청을 합니다.

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

module.exports = function (app) {
	app.use(
		"/api",
		createProxyMiddleware({
			target: "http://localhost:5000",
			changeOrigin: true,
		})
	)
}

그 때를 잊지 못하고(?) 이 미들웨어를 사용했는데 안되더군요. 로컬 환경 한정이라는 것은 나중에 알았습니다.

3. 서버를 만드는 방법??

서버를 만드는 방법 밖엔 없나...
node, express를 써야하나... 하던 때에
혹시나 하는 마음으로 post요청을 get으로 바꿔봤습니다. (뭐든 시도하던 때...ㅠㅠ)

const params = {
  keyword: keyword,
  confmKey: process.env.REACT_APP_API_KEY,
  resultType: 'json',
  countPerPage: 100,
  currentPage: 1,
};

await Axios.get(`https://www.juso.go.kr/addrlink/addrLinkApi.do`, {params: params})
  .then((res) => {
  if (res.data.results.juso.length < 1) {
    setNoSearchResult(true);
  }
  setSearchResult(res.data.results.juso);
})
  .catch((err) => console.log(err));

?! 잘 됩니다.
검색이 너무 잘 됩니다....

과제는 어찌저찌 수행했지만,
제대로 해결하지 못했다는 찝찝함이 남았습니다;;

주말에는 간단히 서버를 만들어서 테스트를 해보려 합니다.

0개의 댓글