코로 넘어져도 헤딩만 하면 그만
CORS에러와 프록시 본문
🚩 CORS에러와 프록시?
브라우저에서 API를 요청할 때, 현재 주소와 API 주소의 도메인이 일치하지 않을 시 CORS 에러를 띄웁니다.
자세히 읽어보면 CORS라고 막혔다는 에러 문구가 보입니다. 따라서 이런 경우를 해결하기 위해서는 CORS설정을 따로 해주어서 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주어야 합니다.
여기서 출처는 '프로토콜, 도메인, 포트'로 정의되며 이 셋이 모두 일치해야 동일 출처라고 말할 수 있습니다.
모든 도메인을 허용해버린다면, 보안상 심각한 결과가 나올 수 있습니다(애초에 CORS 정책이 보안을 위해 마련된 거니까요). 따라서 미리 허가한 출처만 접근이 허용될 수 있게 관리해야 합니다. 이를 위해서 프론트엔드 개발자가 백엔드 개발자에게 프론트엔드 개발 서버 도메인을 허용해 달라고 요청을 해야 하고, 백엔드 개발자는 응답 헤더에 필요한 값들을 담아 전달을 해줍니다.
여기까지가 CORS에러를 해결하기 위한 정석적인 방법이죠.
하지만 이는 프록시 서버를 통해서도 해결할 수 있습니다. 프록시 서란, CORS정책을 우회할 수 있게 하는 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램입니다. 서버와 클라이언트가 직접 통신 하지 않도록 가운데에서 중계해주는 거죠. 이를 통해서 서버에서 응답받은 걸 캐시에 저장해둔 다음, 만약 클라이언트가 같은 요청을 보낼 시 저장해둔 걸 바로 실행할 수 있습니다.
또한 프록시는 보안 기능도 수행하는데요. 클라이언트 IP주소가 서버에 직접 노출되는 상황을 막아줍니다.
그렇다면 프록시 서버는 어떻게 구축할까요?
1. webpack dev server proxy
우선 webpack dev server proxy라는 프록시 기능을 사용해서 브라우저가 API를 요청할 수 있습니다.
아래와 같이 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 주소"
}
그런 뒤에 기존 fetch나 axios를 통해 요청하던 부분에서 도메인을 제거해줍니다.
export async function getAllfetch() {
const response = await fetch('우회할 api주소/params');
.then(() => {
...
})
}
//다음과 같이 바꾼다
export async function getAllfetch() {
const response = await fetch('/params');
.then(() => {
...
})
}
webpack dev server의 proxy를 사용하게 되면, 브라우저 API를 요청할 때 백엔드 서버에 직접적으로 요청을 하지 않고, 현재 개발서버의 주소로 우회 요청을 하게 됩니다. 그러면 웹팩 개발 서버에서 해당 요청을 받아 그대로 백엔드 서버로 전달하고, 백엔드 서버에서 응답한 내용을 다시 브라우저 쪽으로 반환합니다.
2. http-proxy-middleware
이 외에도 http-proxy-middleware 라이브러리 설치를 통해 프록시를 수동으로 적용해줄 수 있습니다.
npm install http-proxy-middleware --save
이후 리액트 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, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분입니다.
})
);
};
그리고 기존의 fetch, 혹은 axios를 통해 요청하던 부분에서 도메인 부분을 제거합니다.
export async function getAllfetch() {
const response = await fetch('우회할 api주소/params');
.then(() => {
...
})
}
//아래와 같이 바꾼다.
export async function getAllfetch() {
const response = await fetch('/params');
.then(() => {
...
})
}
이러면 성공적으로 프록시가 적용되는 것을 볼 수 있습니다.
'CODE STATES 44' 카테고리의 다른 글
Preproject 회고 (0) | 2023.06.27 |
---|---|
CI/CD 및 github action의 workflow (0) | 2023.06.05 |
npm ERR! code ENOENT (0) | 2023.06.02 |
Typescript 맛봄 (2) (0) | 2023.05.31 |
"Cannot read properties of undefined (reading 'pathname')" 에러 (0) | 2023.05.31 |