목차
프로젝트 기본 구조
웹팩
바벨
타입스크립트
CSS전처리
환경변수
정적 파일1(image, svg)
정적 파일2(font)
라우팅
완성파일
저번 글에서는 리엑트와 웹팩 기반 프론트엔드 프로젝트에서 기본적인 웹팩 세팅에 대해 알아보았다.
이번에는 백엔드 및 서드파티 api와 원활한 소통을 위한 프록시 설정에 대해 알아보겠다.
* 이 글은 이전 글인 "[react] cra, vite 없이 직접 리엑트 프로젝트 세팅하기1(webpack) - 바벨, 타입스크립트, css 전처리, 환경변수, 정적 파일"에서 이어진다.
[react] cra, vite 없이 직접 리엑트 프로젝트 세팅하기1(webpack) - 바벨, 타입스크립트, css 전처리, 환
목차프로젝트 기본 구조웹팩바벨타입스크립트CSS전처리환경변수정적 파일1(image, svg)정적 파일2(font)라우팅완성파일 일반적으로 리엑트 프로젝트는 cra나 vite 등의 cli로 자동 세팅이 가능하다.이
chartist1206.tistory.com
프록시에 대한 배경지식
1. 프록시 서버란?
- 네트워크 통신용어에서, 네트워크 통신과정에서 출발지와 도착지 간에 경유하는 네트워크 인터페이스
- 프록시 서버는 클라이언트와 서버, 혹은 서버와 서버 통신간에 요청이 경유하는 서버
- 일반적인 용도는 네트워크 요청들을 1차적으로 보안검사하고 걸러내는 게이트웨이 역할이나 로드 벨런싱, 혹은 클라이언트에게 백엔드의 쿼리 파라미터나 헤더 등 동작 방식을 은폐하는 것이다.
2. 프론트엔드 개발과 프록시 서버의 관계
- 브라우저는 보안상의 이유로 SOP를 준수한다.
- SOP란, same-origin(동일 출처)간에만 요청을 허용하는 정책이다. 여기서 origin은 " 프로토콜 + 호스트 + 포트"를 의미하며, 이 중 하나라도 요청 측과 응답 측이 다르다면 cross-origin이라 부른다.
- cross-origin 요청은 SOP에 따라 기본적으로 브라우저 측에서 해당 요청을 읽기 못하도록 막는다. 하지만 클라이언트는 로컬 개발 프론트엔드에서 실제 배포된 백엔드에 요청을 한다던가 OAuth같은 외부 API를 이용하는 경우가 있는데, 이 때 SOP 정책을 우회하기 위한 설정을 CORS라고 부른다.
- CORS를 설정하기 위해서는 두 가지 방법이 있는데, 하나는 서버 측에서 응답 헤더에 access-control-allow-origin : *. 즉, 모든 origin에 대한 허용을 함으로써 브라우저의 cors에러를 피할 수 있다.
- 하지만, 이 방식은 cross-site 간에 쿠키와 같은 인증 정보 전송을 불가능하게 만든다. 따라서, 로그인 등의 인증 로직에서 타도메인에 쿠키를 보내야 하는 경우, cors에러가 다시 발생한다.
- 이 문제를 피하기 위한 방법 중 하나는 서버에서 로컬 개발 포트를 전부 열어주는 것인데, 이 경우에는 쿠키 보안 관련 문제가 생긴다.
- 쿠키는 CSRF공격, 즉 타 도메인에서 유저의 쿠키를 탈취하여 해커의 서버로 보내는 걸 막기 위해 브라우저에서 여러 제한 옵션을 걸 수 있다. 대표적으로 secure, httpOnly, same-site가 있다.
- secure은 https프로토콜에만 쿠키를 넣을 수 있는 것으로, 암호화되지 않은 http 요청에서 쿠키 정보를 탈취하는 걸 막는다.(로컬 호스트에는 적용되지 않으므로 개발에 영향을 주지 않는다.)
- httpOnly는 자바스크립트 코드에서 도메인의 쿠키에 접근하지 못하도록 만는다.(원래 쿠키는 document.cookies로 접근가능하나, 이 옵션이 설정되면 빈 데이터를 읽어온다)
- same-site는 타도메인에 쿠키를 전송할 수 있는지 여부를 설정한다.
- none | 타도메인 쿠키 전송을 허용(csrf 공격 등에 취약함)
- strict | 타도메인 쿠키 전송을 엄격히 제한함.
- lax | 경우에 따라 타도메인에 쿠키 전송을 허용함
- 안전한 요청 메소드인 GET, HEAD 이어야 함
- 그 이외의 메소드인 경우, 사용자의 상호작용(링크 클릭, 브라우저 리디렉션)이 있어야 쿠키 전송가능
- 이처럼 cors 에러 해결과 cross-site간 쿠키 전송, 그리고 쿠키 관련 보안, 세 가지를 해결하기 위해서 프록시 서버를 사용한다.
- 프론트엔드 측에서 백엔드의 origin과 동일한 프록시 서버를 생성해서 모든 요청을 해당 프록시를 경유하도록 한다.
- 이러면 cors 에러를 피할 수 있고 cross-site간 안전한 쿠키 전송이 가능하다.
- 쿠키는 CSRF공격, 즉 타 도메인에서 유저의 쿠키를 탈취하여 해커의 서버로 보내는 걸 막기 위해 브라우저에서 여러 제한 옵션을 걸 수 있다. 대표적으로 secure, httpOnly, same-site가 있다.
웹팩 설정하기
프론트엔드에서 로컬 서버에 프록시를 설정하는 방법은 일반적으로 3가지이다. 하나는 package.json에서 proxy 속성을 이용하는 것이고, 두번째는 웹팩의 개발 서버 모드의 옵션에서 proxy를 이용하는 것, 마지막은 http-proxy-middleware 라이브러리를 이용하는 것이다.
첫번째는 api 요청 경로에 따라 여러 개의 프록시 서버 처리를 하는 등 복잡한 처리가 어렵고, 세번째는 두번째에 내장되어 있으므로, 두번째 방식인 웹팩을 이용하자.
1. webpack.config.js
웹팩 설정 파일에서 개발 서버를 띄우기 위한 devServer속성이 있을 것이다. 거기에 proxy속성을 추가한다.
아래는 프론트 로컬 서버 " localhost:4000"에서 두api 요청인 "http://localhost:5000/getjson", "http://echo.jsontest.com/echo"를 프록시 서버로 경유하는 설정이다.
proxy: [
{
context: ["/getjson"],
target: "http://localhost:5000",
secure: false,
changeOrigin: true,
},
{
context: ["/echo"],
target: "http://echo.jsontest.com",
secure: false,
changeOrigin: true,
},
],
각 속성에 대한 설명
- context | 프록시 서버를 이용할 pathname이다. 예컨대, "getjson"이 있으면, 해당 path를 포함하는 모든 요청은 프록시 서버를 경유한다.
- target | 프록시 서버가 사용할 origin이다. 백엔드와의 origin 일치를 위해서 백엔드의 도메인과 동일하게 설정하는 것이 일반적이다.
- secure | 프록시 서버가 목적지 서버에 https 설정을 확인할지 여부이다. false로 되어 있으면 https 여부 상관없이 통신한다.
- changeOrigin | 호스트인 프론트 로컬 서버의 헤더를 프록시의 origin으로 덮어쓸지 결정한다. 외부 도메인과의 통신을 위해 true로 설정하는 것이 일반적이다.
2. 요청 방법
이제 프론트 로컬 서버인 localhost:4000으로 두 요청을 보내자.
(이 때 주의할 점은)
그러면 프록시 설정에 따라 각각 localhost:4000/getjson은 http://localhost:5000/getjson으로, localhost:4000/echo는 http://echo.jsontest.com/echo로 서버에 전송된다.
3. 콜백 설정
해당 프록시 요청에다가 추가적인 콜백 설정을 하려면 아래처럼 추가한다.
{
context: ["/getjson", "/getjson2", "/setAnotherCookie"],
target: "http://localhost:5000",
secure: false,
changeOrigin: true,
// 동적 작업용
router: function (req) {},
onProxyReq: (proxyReq, req, res) => {},
onProxyRes: (proxyRes, req, res) => {
/* handle proxyRes */
// console.log("proxyRes", proxyRes);
// console.log("proxyRes.cookie", proxyRes.header);
},
onError: (err, req, res) => {
/* handle error */
},
},
각 속성에 대한 설명
- router | 요청할 target을 동적으로 재설정한다.
- onProxyReq, onProxyRes | 프록시 요청에 동적인 콜백을 추가한다.
4. 추가적인 설정방법
위에서 서술한 속성들은 웹팩 공식문서에서 다루나, 그 이외의 속성들은 다루지 않는다.
대신, 웹팩의 프록시 설정은 webpack-devServer 라이브러리를 사용하고, 이 라이브러리는 http-proxy-middleware의 설정을 사용하므로, 해당 라이브러리의 공식문서에 있는 옵션들을 webpack.config.js의 devServer.proxy에서 그대로 사용하면 된다.
http-proxy-middleware의 공식문서
https://www.npmjs.com/package/http-proxy-middleware#http-proxy-options
http-proxy-middleware
The one-liner node.js proxy middleware for connect, express, next.js and more. Latest version: 3.0.3, last published: a month ago. Start using http-proxy-middleware in your project by running `npm i http-proxy-middleware`. There are 4138 other projects in
www.npmjs.com
테스트용 프로젝트의 github
https://github.com/charchar111/test-proxy-webpack
GitHub - charchar111/test-proxy-webpack: this project is test for dev proxy server(webpack-dev-server) in react+webpack architec
this project is test for dev proxy server(webpack-dev-server) in react+webpack architecture - charchar111/test-proxy-webpack
github.com
'프로그래밍 일반 > 프론트엔드' 카테고리의 다른 글
웹 폰트의 동작 방식 (2) | 2024.11.13 |
---|---|
빌드한 파일을 실제 배포 환경처럼 실행해보기(serve) (0) | 2024.11.07 |
[프론트엔드] public 폴더와 src 폴더의 차이 (0) | 2024.11.06 |
[모노레포, 마이크로 프론트엔드(MF)] 호스트 앱과 리모트 앱 동시 실행하기 (1) | 2024.11.04 |
[react] cra, vite 없이 직접 리엑트 프로젝트 세팅하기1(webpack) - 바벨, 타입스크립트, css 전처리, 환경변수, 정적 파일 (0) | 2024.08.18 |