도로명주소 공공api를 이용하는 과제가 주어졌습니다.
도로명주소 api
https://www.juso.go.kr/addrlink/devAddrLinkRequestGuide.do?menu=roadApi
주소검색API는은 2가지로, 팝업창이 열리고 주소검색을 할 수 있도로 하는 팝업 API와
곧장 검색을 할 수 있는 검색API가 있었습니다.
만들어둔 ui에서 직접 검색이 되도록 하는 방안으로 해야해서 검색API를 이용했습니다.
검색은 키워드, 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 정책 때문에 요청이 막혔다는 얘기...
대부분의 웹 브라우저는 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)이 다르다는 것입니다.
어떻게 고칠 수 있을지 온갖 실험을 해봤습니다.
저는 요청만 가능하고 서버를 제어할 수 있는 상황이 아니기 때문에, 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/
서버를 구축하기에는 시간이 부족했습니다..ㅠㅠ 다른 방법을 찾기로..
이미 길을 먼저 밟으신 선배님들께서 유용한 정보들을 블로그에 많이 남겨두셨습니다.(만세)
다른 사람이 만든 proxy server를 이용해 HTTP응답 해더의 Access-Control-Allow-Origin를 설정 방법을 이용했습니다.
이 주소를 url앞에만 넣어주면 됩니다. 이렇게 하면 중간에 요청을 가로채 HTTP 응답 헤더에 Access-Control-Allow-Origin: * 로 설정해 응답한다고 합니다.
예전 프로젝트를 진행할 때 서버는 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,
})
)
}
그 때를 잊지 못하고(?) 이 미들웨어를 사용했는데 안되더군요. 로컬 환경 한정이라는 것은 나중에 알았습니다.
서버를 만드는 방법 밖엔 없나...
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));
?! 잘 됩니다.
검색이 너무 잘 됩니다....
과제는 어찌저찌 수행했지만,
제대로 해결하지 못했다는 찝찝함이 남았습니다;;
주말에는 간단히 서버를 만들어서 테스트를 해보려 합니다.