💡 브라우저에서 기본적으로 API를 요청시, 브라우저의 현재 주소와 API의 주소의 도메인이 일치해야만 데이터를 접근 할 수 있게 하는 것이 원칙
💡 다른 도메인에서 API를 요청해서 사용하려면 CORS 설정이 필요
CORS
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
출처(origin)
접근할 때 사용하는 URL의 스킴(프로토콜), 호스트(도메인), 포트로 정의
두 객체의 스킴, 호스트, 포트가 모두 일치하는 경우 같은 출처로 봄
💡 라이브 데이터는 민감성이 높은 데이터들이 위주이기 때문에 보안이 무엇보다 중요
💡 서비스가 모든 출처의 접근을 허용하면 보안성이 낮아지고, 해킹 위험에 그대로 노출됨
라이브 데이터
실제 서비스되고 있는 앱의 데이터베이스에 적재되고 있는 데이터
💡 프론트엔드 개발자가 백엔드 개발자에게 프론트엔드 개발 서버 도메인을 허용 요청,
백엔드 개발자는 응답 헤더에 필요한 값들을 담아서 전달
💡 Proxy 사용
💡 CORS 정책을 우회하는 방법
💡 클라이언트에서 데이터를 요청, 해당 요청을 서버로 전달, 서버로부터 받은 응답 데이터를 다시 브라우저로 전달하는 방법
📗 proxy 적용 전
FrontEnd ➡️ (리소스 요청) ➡️ Browser
Browser ➡️ (접근 권한이 있는지 확인) ➡️ BackEnd
Browser ⬅️ (응답 - 200 OK) ⬅️ BackEnd
FrontEnd ⬅️ (응답 파기 여부 결정) ⬅️ Browser
✅ Browser
받은 리소스 및 응답과 함께 출처가 같은지 아닌지 확인
출처가 다르다면 응답을 파기(CORS Error),
출처가 같다면 프론트엔드 쪽으로 응답 전달
📗 proxy 적용 후
FrontEnd ➡️ (리소스 요청) ➡️ Browser
FrontEnd ➡️ (프록시 : 프록시를 통한 우회 요청) ➡️ BackEnd
FrontEnd ⬅️ (프록시 : 프록시를 통한 우회 응답) ⬅️ BackEnd
FrontEnd ➡️ (받은 응답을 전달) ➡️ Browser
✅ CORS ERROR가 나지 않음
📗 webpack dev server proxy
webpack dev server 에서 제공하는 proxy는 전역적인 설정
브라우저 API를 요청할 때 현재 개발서버의 주소로 우회 요청
웹팩 개발 서버에서 해당 요청을 받아 그대로 백엔드 서버로 전달
백엔드 서버에서 응답한 내용을 다시 브라우저쪽으로 반환
프록시 설정
//package.json(CRA 경우)
"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 주소"
}
도메인 부분 제거
//api 주소 제거 전
export async function getAllfetch() {
const response = await fetch('우회할 api주소/params');
.then(() => {
//...
})
}
//api 주소 제거 후
export async function getAllfetch() {
const response = await fetch('/params');
.then(() => {
//...
})
}
📗 React Proxy
webpack dev server에서 충분히 적용되지 않는 경우
http-proxy-middleware 라이브러리를 사용
http-proxy-middleware 라이브러리 설치
npm install http-proxy-middleware --save
프록시 설정
//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 주소 제거 전
export async function getAllfetch() {
const response = await fetch('우회할 api주소/params');
.then(() => {
//...
})
}
//api 주소 제거 후
export async function getAllfetch() {
const response = await fetch('/params');
.then(() => {
//...
})
}
두 개 이상
//src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
['/api', '/api2'],
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
router : {
'/api2' : 'http://localhost:5001'
}
})
);
};
코드스테이츠 교과서