๋ชฉ์ฐจ
์ธ์ฃผ ์์ ๋์ค api์ ์์ฒญ์ ํ ๋ CORS ์๋ฌ๋ฅผ ๋ง์ฃผํ์๋ค!
๋๋ต ์์ ๊ฐ์ ์๋ฌ ๋ฉ์ธ์ง๋ฅผ ์ฝ์์ฐฝ์์ ๋ณผ ์ ์๋ค.
1. CORS (Cross Origin Resource Sharing)
1) CORS๋?
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS/Errors
CORS(๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ )๋ ๋ค๋ฅธ ์ถ์ฒ ๊ฐ์ ์์ ๊ณต์ ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๊ณ
http ํค๋๋ฅผ ์ด์ฉํ์ฌ
์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ถ์ฒ(Origin)์ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก
๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์ ์ด๋ค.
2) SOP (Same Origin Policy)
https://developer.mozilla.org/ko/docs/Web/Security/Same-origin_policy
CORS ์๋ฌ๊ฐ ๋ฐ์ํ๋ ์ด์ ๋ฅผ ์์๋ณด๊ธฐ ์ ์ ๋จผ์ SOP์ ๋ํด์ ์์๋ณด์.
SOP(๋์ผ ์ถ์ฒ ์ ์ฑ )๋ ๊ฐ์ ์ถ์ฒ(Origin)์์๋ง ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ๋ ๊ท์น์ ๊ฐ์ง ์ ์ฑ ์ด๋ค.
์ด ์ ์ฑ ์ ์ด์ฉํ์ฌ ์ธ๋ถ์ ํ๊ฐ๋์ง ์์ ์์ฒญ์ ๋ฐฉ์ดํ ์ ์๋ค.
์ฌ๊ธฐ์์ ๋์ผ ์ถ์ฒ๋ ์ด๋ค ๊ฒ์ ๋งํ๋ ๊ฒ์ผ๊น?
์์ URL์์ protocol, host, port ๊ฐ ๊ฐ์ ๊ฒฝ์ฐ ๋์ผ ์ถ์ฒ์ด๋ค.
์ด SOP์ ๋ฐํ์ฌ ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค๊ฐ ํ์ํ ๊ฒฝ์ฐ CORS๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด๋ค.
3) CORS ์๋ฌ
CORS ์๋ฌ๋ ํด๋ผ์ด์ธํธ์์ ์๋ฒ(API)์ ์ ๊ทผํ์ฌ ๋ฆฌ์์ค๋ฅผ ๋ฐ์์ฌ ๋
๋ง์ฝ ๋์ผ ์ถ์ฒ๊ฐ ์๋ ๊ฒฝ์ฐ CORS Error๋ฅผ ๋ฐํํ๋ค.
์ด ๋ฌธ์ ๋ฅผ ์๋ฒ ์ฐจ์์์ ํด๊ฒฐํ๋ ค๋ฉด
CORS ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, Access-access-control-allow-origin ํค๋๋ฅผ ์ธํ ํด์ฃผ์ด์ผํ๋ค.
๋ง์ฝ, ์๋ฒ๋ฅผ ์ง์ ์์ ํ ์ ์๋ ์ํฉ์ด๊ฑฐ๋ ํ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ
ํด๋ผ์ด์ธํธ์์ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํฉ๋๋ค.
์ด ์ํฉ์ด ํ์ฌ ๋ด๊ฐ ๋ง์ฃผํ ๊ฒ์ด๋ค!
2. React์์ CORS ์๋ฌ ํด๊ฒฐํ๊ธฐ
https://create-react-app.dev/docs/proxying-api-requests-in-development/
(๊ณต์ ๋ฌธ์)
ํด๋ผ์ด์ธํธ์์ CORS ์๋ฌ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ํ๋ก์ ์๋ฒ๋ฅผ ์ด์ฉํด์ผํ๋ค.
(ํ๋ก์ ์๋ฒ == ๋ค๋ฅธ ๋คํธ์ํฌ์ ๊ฐ์ ์ ์ํ ์ ์๊ฒ ํด์ฃผ๋ ์๋ฒ)
์ฆ, ํ๋ก์ ์๋ฒ๋ฅผ ํตํด ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ฌ ์๋ฒ์ ๋์ผ ์ถ์ฒ๋ก ๋ง๋๋ ๊ฒ์ด๋ค.
์ด๋ฅผ ์ํ ๋ฐฉ๋ฒ์ 2๊ฐ์ง๊ฐ ์กด์ฌํ๋ค.
1) package.json์ proxy ์ถ๊ฐํ๊ธฐ
//package.json
{
...
"proxy": "์ํ๋ ์๋ฒ(api)์ฃผ์"
}
์์ ๊ฐ์ด package.json์ ์์ ํ๋ฉด
axios๋ฅผ ํตํ response๋ฅผ ํ ๋ localhost:3000์ ๋ฑ๋กํ ์ฃผ์๋ก ๋ณ๊ฒฝํ๋ค.
ํ์ง๋ง ์ด ๋ฐฉ๋ฒ์ ํ๋์ api ์ฃผ์์์๋ง ๊ฐ๋ฅํ๋ฏ๋ก
์ฌ๋ฌ api๋ฅผ ํ์ฉํ๊ณ ์ถ์ ๋๋ ์ ์ ํ์ง ์๋ค.
2) http-proxy-middleware ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉํ๊ธฐ
(1) ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
npm install http-proxy-middleware
(2) src/setupProxy.js ์์ฑ ๋ฐ ์ธํ
//setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
createProxyMiddleware('/๊ฒฝ๋ก1', {
target: '์ํ๋ ์ฃผ์',
changeOrigin: true,
}),
);
app.use(
createProxyMiddleware('/๊ฒฝ๋ก2', {
target: '์ํ๋ ์ฃผ์',
changeOrigin: true,
}),
);
...
};
โ createProxyMiddleware ('/๊ฒฝ๋ก', { ... }) : '/๊ฒฝ๋ก' ๋ก ์์ํ๋ endpoint๋ฅผ ๊ฐ์ง api๋ฅผ ๋งค์นญ์ํจ๋ค.
(endpoint == ๊ฐ์ URL์์ ์๋ก ๋ค๋ฅธ ์์ฒญ์ ํ๋๋ก ๊ตฌ๋ณํ๊ฒ ํด์ฃผ๋ ๊ฒ)
โก target : url์ endpoint ๋ค์ ์ ์ธํ ์ถ์ฒ (์ฆ, ๊ฐ์ฅ base url)
โข changeOrigin : ํธ์คํธ ํค๋์ ์ถ์ฒ๋ฅผ target์ผ๋ก ๋ฐ๊ฟ ๊ฒ์ธ์ง ์ฌ๋ถ (true๋ก ํด์ผ ํจ!)
(3) App.js์์ ์์ฒญ
// App.js
//POST ์์ฒญ์ผ ๊ฒฝ์ฐ ์์
//ํด๋ฆญ ์ด๋ฒคํธ ๊ด๋ จ ํจ์ ๋ฑ
const handleSubmit = async (event)=>{
event.preventDefault();
axios.post('/๊ฒฝ๋ก1', //setupProxy.js์ ์ถ๊ฐํ endpoint์ด์ด์ผ ํจ
{
// ์์ฒญ์ ๋ด์ ๊ฒ ์ถ๊ฐ
},{withCredentials : true})
.then((res)=>{
console.log(res);
})
.catch((error)=>{
console.log(error);alert("ERROR");
})
...
}
//GET ์์ฒญ์ผ ๊ฒฝ์ฐ ์์
{
...
async function fetchdata() {
const { data } = await axios.get(
'/๊ฒฝ๋ก2',
);
console.log(data);
...
}
์์ ๊ฐ์ด POST, GET ์์ฒญ์ App.js์์ ์ ์ํ๋ค.
๋!
์์ โผ
์์) ๋ก๊ทธ์ธ POST
//App.js
const LoginForm = () =>{
const [values, setValues] = useState({
loginId: "",
password: "",
});
const [error, setError] = useState(undefined);
const handleSubmit = async (event)=>{
event.preventDefault();
axios.post("/login",
{
loginId: values.loginId,
password: values.password,
},{withCredentials : true})
.then((res)=>{
console.log(res);
})
.catch((error)=>{
console.log(error);alert("ERROR");
})
};
return(
<div className="login-page-container">
<form onSubmit={handleSubmit}>
<div className="field">
<label htmlFor="loginId">์์ด๋</label>
<input
type="text" name='loginId'
onChange={(e)=>setValues({...values, loginId: e.target.value})}
value={values.loginId}
/>
</div>
<div className="field">
<label htmlFor="password">๋น๋ฐ๋ฒํธ</label>
<input
type="password" name='password'
onChange={(e)=>setValues({...values, password: e.target.value})}
value={values.password}
/>
</div>
{error ? <p className='error'>{error}</p> : <p></p>}
<button type='submit' className='loginBtn'>๋ก๊ทธ์ธ</button>
<button>ํ์๊ฐ์
</button>
</form>
</div>
);
}
//setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app){
app.use(
createProxyMiddleware('/login',{
target:"https://www.kassid.net",
changeOrigin: true,
})
)
};
'๐ | WEB DEV > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] 8. ๋ค๋ฅธ ํ์ผ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ (0) | 2023.07.06 |
---|---|
[React] 7. ์ด๋ฏธ์ง ์ฝ์ ํ๊ธฐ(css, html, publicํด๋์์ ๊ฐ์ ธ์ค๊ธฐ) (0) | 2023.07.03 |
[React] 6. props (0) | 2023.05.29 |
[React] 5. ๋ฐ๋ณต๋๋ ๋ถ๋ถ ์ถ์ฝํ๊ธฐ (map) (0) | 2023.05.28 |
[React] 4. ๋์ ์ธ UI ์ ์ํ๊ธฐ (0) | 2023.05.28 |
๋๊ธ