๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒŒ | WEB DEV/React

[React] CORS ์—๋Ÿฌ ํ•ด๊ฒฐํ•˜๊ธฐ (http-proxy-middleware)

by KASSID 2023. 6. 30.

์™ธ์ฃผ ์ž‘์—… ๋„์ค‘ 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 ๋ฐˆ๐Ÿฅน)

 

์ด ๋ฌธ์ œ๋ฅผ ์„œ๋ฒ„ ์ฐจ์›์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด

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,
    })
  )
};

 

๋Œ“๊ธ€