CORS ์ ์ฑ ์ ํ์์ฑ
CORS (๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ , Cross-Origin Resource Sharing) CORS๋ ์ถ๊ฐย HTTP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ, ํย ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์ ์ด๋ค.
์ค์ ์๋น์ค๊ฐ ๋๋ ์์ฉ ์ฑ์ ์ด์ํ๋ค๋ฉด, ํด๋ผ์ด์ธํธ ๋ค์ ์๋ ์๋ฒ์ ์ฐ๊ฒฐ๋ DB์๋ ๋ผ์ด๋ธ ๋ฐ์ดํฐ๊ฐ ์์ธ๋ค. ์ด๋ฐ ๋ผ์ด๋ธ ๋ฐ์ดํฐ๋ ๋ฏผ๊ฐ์ฑ์ด ๋์ ๋ฐ์ดํฐ๋ค ์์ฃผ๋ก ์ด๋ฃจ์ด์ ธ์๊ธฐ ๋๋ฌธ์ ์๋ฒ์์ ๋ชจ๋ ์ถ์ฒ์ ์ ๊ทผ์ ํ์ฉํ๋ค๋ฉด ๋ณด์์ฑ์ด ๋ฎ์์ง๊ณ ํดํน์ ์ํ์ ๊ทธ๋๋ก ๋ ธ์ถ๋๋ค.
์ด๋ฅผ ์ํด์๋ ํน์ ๋๋ฉ์ธ๋ง ํ์ฉํ๋๋ก ๊ฐ ๊ฐ๋ฐ์ ๊ฐ ํ์๊ฐ ํ์ํ๋ค. ํด๋ผ์ด์ธํธ(ํ๋ก ํธ) ๊ฐ๋ฐ์๋ ๊ฐ๋ฐ ์๋ฒ ๋๋ฉ์ธ์ ํ์ฉํด๋ฌ๋ผ ์์ฒญํ๊ณ , ์๋ฒ(๋ฐฑ์๋) ๊ฐ๋ฐ์๋ ํด๋น ๋๋ฉ์ธ๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๋๋ก CORS ํค๋ ์ค์ ์ ํ๋ฉด ๋๋ค.
Proxy
ํ๋ก์ ์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ฌ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ฃผ๋ ์ญํ ์ ํ๋ ์ผ์ข ์ ์ค๊ณ ์๋ฒ์ด๋ค. ํด๋น ๊ตญ๊ฐ IP๋ฅผ ์ฐํํ๊ฑฐ๋ ์๋ฒ์ธก์์ ์ฐจ๋จํ IP๋ฅผ ์ฐํํ๋ ๋ฑ ๋ง์ ๊ณณ์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ์ง๋ง(์์ข์ ์ชฝ์ผ๋ก๋), ์น ๊ฐ๋ฐ ์์๋ CORS ์ ์ฑ ์ ์ฐํํ๊ธฐ ์ํด ์ฌ์ฉํ๊ธฐ๋ ํ๋ค. React ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํน์ Webpack Dev Server์์ Proxy ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์๋ค.
proxy๋ฅผ ์ ์ฉํ๊ธฐ ์ ์๋ React ์ฑ์์ ๋ธ๋ผ์ฐ์ ์ชฝ์ผ๋ก ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ค. ๋ธ๋ผ์ฐ์ ๋ ์๋ฒ์ ์์ฒญ์ ๋ณด๋ผ ๋ ์ ๊ทผ ๊ถํ์ด ์๋์ง ํ์ธํ๋๋ฐ, ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก 200 OK ์๋ต์ ๋ณด๋ด๋๋ผ๋ ๋ธ๋ผ์ฐ์ ๋ ์ถ์ฒ๊ฐ ๊ฐ์์ง ํ์ธํ๊ธฐ ๋๋ฌธ์ ์ถ์ฒ๊ฐ ๋ค๋ฅด๋ฉด ์๋ต์ ํ๊ธฐ(CORS Error) ํ๊ฒ ๋๋ค.
proxy๋ฅผ ์ ์ฉํ๊ฒ ๋๋ฉด React ์ฑ์์ proxy๋ฅผ ํตํด ์๋ฒ๋ก ์์ฒญ์ ์ฐํํ์ฌ ๋ณด๋ด๊ฒ ๋๋ค. ์๋ฒ๋ ์๋ต์ React ์ฑ์ผ๋ก ๋ณด๋ด๊ณ , React ์ฑ์ ๋ฐฑ์๋ ์๋ฒ ๋์ ๋ธ๋ผ์ฐ์ ์๊ฒ ์ ๋ฌํ๋ค. React ์ฑ์ ๊ฒฐ๊ตญ ํด๋ผ์ด์ธํธ์ ๋์ผ ์ถ์ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๋ ์ด ์ฌ์ค์ ๋์น ์ฑ์ง ๋ชปํ๊ณ ํ์ฉํ๊ฒ ๋๋ค.
webpack dev server proxy ์ฌ์ฉ๋ฒ
webpack dev server์์ ์ ๊ณตํ๋ proxy ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ๋ธ๋ผ์ฐ์ API๋ฅผ ์์ฒญํ ๋ ๋ฐฑ์๋ ์๋ฒ์ ์ง์ ์์ฒญ์ ๋ณด๋ด์ง ์๊ณ ํ์ฌ ๊ฐ๋ฐ์๋ฒ์ ์ฃผ์๋ก ์ฐํ ์์ฒญ์ ๋ณด๋ธ๋ค. ์นํฉ ๊ฐ๋ฐ ์๋ฒ์์๋ ํด๋น ์์ฒญ์ ๋ฐ์ ๊ทธ๋๋ก ๋ฐฑ์๋ ์๋ฒ๋ก ์ ๋ฌํ๊ณ , ๋ฐฑ์๋ ์๋ฒ์์ ์๋ตํ ๋ด์ฉ์ ๋ค์ ๋ธ๋ผ์ฐ์ ๋ก ๋ฐํํ๊ฒ ๋๋ค.
...
"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 ์ฃผ์"
}
์นํฉ ๊ฐ๋ฐ์๋ฒ์ proxy ์ค์ ์ ์๋ ์นํฉ ์ค์ ์ ํตํด์ ์ ์ฉ์ ํ์ง๋ง, CRA๋ฅผ ํตํด ๋ง๋ ๋ฆฌ์กํธ ํ๋ก์ ํธ์์๋ ์์ ์ฝ๋์ฒ๋ผ package.json
์์ โproxyโ
๊ฐ์ ์ค์ ํ๋ฉด ํ๋ก์ ์ค์ ์ด ๊ฐ๋ฅํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ธฐ์กด์ fetch๋ axios๋ฅผ ํตํด ์์ฒญ์ ๋ณด๋ด๋ ๋ถ๋ถ์์ ๋๋ฉ์ธ ๋ถ๋ถ์ ์ ๊ฑฐํ๋ฉด ๋๋ค.
export async function getAllfetch() {
const response = await fetch('์ฐํํ api์ฃผ์/params');
.then(() => {
...
})
}
// proxy ์ค์ ํ
export async function getAllfetch() {
const response = await fetch('/params');
.then(() => {
...
})
}
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, //๋์ ์๋ฒ ๊ตฌ์ฑ์ ๋ฐ๋ผ ํธ์คํธ ํค๋๊ฐ ๋ณ๊ฒฝ๋๋๋ก ์ค์ ํ๋ ๋ถ๋ถ
})
);
};
๊ทธ๋ฆฌ๊ณ ๊ธฐ์กด์ fetch๋ axios๋ฅผ ํตํด ์์ฒญ์ ๋ณด๋ด๋ ๋ถ๋ถ์์ ๋๋ฉ์ธ ๋ถ๋ถ์ ์ ๊ฑฐํ๋ฉด ๋๋ค.
export async function getAllfetch() {
const response = await fetch('์ฐํํ api์ฃผ์/params');
.then(() => {
...
})
}
// proxy ์ค์ ํ
export async function getAllfetch() {
const response = await fetch('/params');
.then(() => {
...
})
}
// ์ฌ๋ฌ api ์ฌ์ฉ ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
// 1. app.use๋ฅผ ์ฌ๋ฌ ๋ฒ ์์ฑํ๋ ๋ฐฉ๋ฒ
module.exports = (app) => {
app.use('/api',
createProxyMiddleware({
target: 'http://localhost:3080',
changeOrigin: true,
})
)
app.use('/api1',
createProxyMiddleware({
target: 'http://localhost:3070',
changeOrigin: true,
})
);
};
// 2. router๋ฅผ ํ์ฉํด ์ค๋ณต์์ฑ์ ํ์ง ์๋ ๋ฐฉ๋ฒ
module.exports = (app) => {
app.use(
['/api','/api2'],
createProxyMiddleware({
target: 'http://localhost:3080',
changeOrigin: true,
router: {
'/api2': 'http://localhost:3070'
}
})
);
};
Uploaded by N2T