● 오늘 배운 것
- proxy
이전에, 개인적으로 프로젝트를 진행하면서 네이버 REST API를 활용하려다가, CORS 에러를 마주한 적이 있었습니다. API마다 CORS를 허용해놓거나, 해놓지 않는 경우가 있다는 것도 알게되었습니다. 코드스테이츠에서 프로젝트 진행할 때는 만들어주신 API를 통해서 항상 실습을 진행했기 때문에 대체로 CORS 에러를 마주한적이 많지 않았습니다. 대체로 대기업에서 제공해주는 API같은 경우에는 CORS를 허용해놓지 않는 경우가 많기 때문에 이를 해결해야하는 경우가 많아보였습니다. 그리고 AP마다 데이터를 XML로 보내주는지, JSON의 형태로 보내는지도 다르다는 것을 알게 되었습니다. 늘 편하게 사용하기 쉬운 JSON의 형태로 실습을 진행하였기 때문에 이런 부분도 알기 좋았던 것 같습니다.
원래 네이버도 2021년도에만해도 CORS를 허용해놓았었는데, 보안상 그 이후로부터는 CORS가 생긴 것 같더군요 ㅠ.. 그래서 아래의 블로그를 통해서 proxy를 설정해주는 방법을 통해서 해결할 수 있었습니다.
네이버 쇼핑 API 불러오기
리액트에서 axios를 이용하여 네이버 open api를 불러와 보자! 블로깅에 오류가 있다면 말씀해주세요! 학습에 큰 도움이 됩니다!
velog.io
- proxy란 무엇인가?
클라이언트는 늘 브라우저를 통해서 서버에 요청을 보내게 됩니다. 따라서 브라우저는 기본적으로 CORS 정책을 설정해두고 있기 때문에, Same-origin이 아니라면 CORS에러를 보게 됩니다. 그래서 이를 해결하기 위해선 요청을 보낼 때 CORS 설정을 해주어야했고 서버쪽에서도 클라이언트의 Origin을 등록을 해주어야 요청이 가능했습니다. 서버 쪽에서 모든 Origin을 허용해 놓으면 보안상 문제가 생길 수 있기 때문에 모든 Origin을 허용해놓을 수도 없는 노릇이었읍니다. . 그래서 이런 방식이 생기게 된 것입니다. 하지만 서버측에서 클라이언트의 origin을 설정할 수 없고, 클라이언트는 당장 요청을 하고 응답을 받아야한다면?
이런 경우에 proxy서버가 필요한 것입니다. CORS의 제어를 받지 않는 경우는 서버끼리 통신할 때이기 때문입니다. 따라서 클라이언트 측에서 proxy서버를 활용해 요청을하고, 그 응답을 받아올 수 있습니다.
위의 그림은 proxy를 적용해 브라우저를 속인 후 흐름입니다. React 앱에서 브라우저를 통해 API를 요청할 때, proxy를 통해 백엔드 서버로 요청을 우회하여 보내게 됩니다. 그러면 백엔드 서버는 응답을 React 앱으로 보내고, React 앱은 받은 응답을 백엔드 서버 대신 브라우저에게 전달합니다. 이렇게 되면 출처가 같아지기 때문에 브라우저는 이 사실을 눈치채지 못하고 허용하게 됩니다.
- proxy 사용법
webpack dev server proxy
먼저 webpack dev server에서 제공하는 proxy 기능을 사용하는 방법이 있습니다. webpack dev server의 proxy를 사용하게 되면, 브라우저 API를 요청할 때 백엔드 서버에 직접적으로 요청을 하지 않고, 현재 개발서버의 주소로 우회 요청을 하게 됩니다. 그러면 웹팩 개발 서버에서 해당 요청을 받아 그대로 백엔드 서버로 전달하고, 백엔드 서버에서 응답한 내용을 다시 브라우저 쪽으로 반환합니다.
웹팩 개발서버의 proxy 설정은 원래 웹팩 설정을 통해서 적용을 하지만, CRA를 통해 만든 리액트 프로젝트에서는 package.json 에서 "proxy" 값을 설정하여 쉽게 적용할 수 있도록 구성이 되어 있습니다.
...
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy" : "우회할 API 주소"
}
React Proxy 사용법
webpack dev server에서 제공하는 proxy는 전역적인 설정이기 때문에, 종종 해당 방법이 충분히 적용되지 않는 경우가 생기기도 합니다. 그래서 수동으로 proxy를 적용해줘야 하는 경우가 있는데, 이때는 http-proxy-middleware 라이브러리를 사용해야 합니다.
http-proxy-middleware 라이브러리 설치
npm install http-proxy-middleware --save
그리고 React App의 src 파일 안에서 setupProxy.js 파일을 생성하고, 안에서 설치한 라이브러리 파일을 불러온 다음, 아래와 같이 작성을 합니다.
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api', //proxy가 필요한 path prameter를 입력합니다.
createProxyMiddleware({
target: 'http://localhost:5000', //타겟이 되는 api url를 입력합니다.
changeOrigin: true, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분입니다.
})
);
};
과제를 진행하면서 /api? 가 도대체뭘까 use 사용 바로 다음 오는 파라미터를 어떻게 써야하는지에 대한 고민이 있었습니다.
src> setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api2', //proxy가 필요한 path prameter를 입력합니다.
createProxyMiddleware({
target: 'http://localhost:3070', //타겟이 되는 api url를 입력합니다.
changeOrigin: true, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분입니다.
})
);
app.use(
'/api', //proxy가 필요한 path prameter를 입력합니다.
createProxyMiddleware({
target: 'http://localhost:3080', //타겟이 되는 api url를 입력합니다.
changeOrigin: true, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분입니다.
})
);
};
target에 원하는 api url을 넣어주고, api같은 경우에는 url 파라미터!를 적어주는 것이었읍니다.. 이걸로 조금 헤맸던 것 같아요.
각각 fetch해주는 api/books 이런식으로 파라미터를 넣어주면 되는 것이엇 읍니다..
export const getAllBooks = async () => {
const response = await fetch('/api/books');
return await response.json();
}
export const createBook = async (data) => {
const response = await fetch('/api/book', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({book: data})
})
return await response.json();
}
export const getAllTodos = async () => {
const response = await fetch('api2/todos');
return await response.json();
}
export const createTodo = async (data) => {
console.log(data);
const response = await fetch('api2/todo', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({todo: data})
})
return await response.json();
}
그래서 쉽게 해결할 수 있었다~!
proxy로 전역설정해줘도 안될때가 좀 있었는데, http-proxy-middleware를 활용하니까 완전 편하게 프록시 서버를 설정할 수 있다는 것을 알게 되었읍니다.. 다음에 api를 통해서 데이터를 받아와야할때 써먹으면 좋을 것 같다는 생각이 들었습니다.
https://www.npmjs.com/package/http-proxy-middleware
http-proxy-middleware
The one-liner node.js proxy middleware for connect, express and browser-sync. Latest version: 2.0.6, last published: a year ago. Start using http-proxy-middleware in your project by running `npm i http-proxy-middleware`. There are 3466 other projects in th
www.npmjs.com
보니까 npm에서 옵션에 대한 자세한 정보도 알 수 있었습니다. 웹소켓 설정도 할 수 있고, router 설정옵션으로 프록시 설정도 할 수 있는 것 같았습니다. :)
● 총정리
클라이언트 측에서 proxy라는 가서버(?)를 활용해서 서버에 요청하고, 서버는 가서버에 응답하는 식으로 요청과 응답이 이루어진다.
브라우저 > React proxy 서버 > 백엔드 서버 응답 > React proxy 서버 브라우저에 응답 > 브라우저가 응답을 받음
● 이외에 공부한 것
- solo-project typescript 리팩토링 완성
GitHub - ddaeunbb/solo-shoppingmall: shoppingmall-solo-project
shoppingmall-solo-project. Contribute to ddaeunbb/solo-shoppingmall development by creating an account on GitHub.
github.com
오늘에서야.. ReadMe 파일까지 수정완료하고, 리팩토링을 마칠 수 있었습니다.
오늘부터 또 2차 리팩토링을 진행하고 있습니다.
- 리덕스 thunk
- RTK Query
- react-intersection-observer 라이브러리를 활용한 무한스크롤
dark mode theme
시간이 된다면
- prettier 세부설정
- eslint 세부설정
- husky
를 진행할 예정입니다. :)
오늘은 theme-provider를 진행해보았습니다.