๐Ÿ”‘Code/React

React | REST API๋ฅผ ์ด์šฉํ•œ Kakao ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

pajiyeee 2023. 5. 14. 00:30

2์ฐจ ํ”„๋กœ์ ํŠธ '๋ฎค์ฆˆ'์—์„œ๋Š” ๋น ๋ฅด๊ณ  ๊ฐ„ํŽธํ•œ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋ ค๋Š” ๋ชฉ์ ๋„ ์žˆ์—ˆ๊ณ 
๋‹ค๋ฅธ ์›น์—์„œ ๋งŽ์ด ์“ฐ์ด๋Š” ์™ธ๋ถ€ API๋ฅผ ์จ๋ณด๊ณ  ์‹ถ๊ธฐ๋„ ํ•ด์„œ ์นด์นด์˜ค ์†Œ์…œ ๋กœ๊ทธ์ธ API๋ฅผ ์—ฐ๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ•ด์„œ ์ง„ํ–‰ํ–ˆ๋‹ค.
 

์นด์นด์˜ค API ๋กœ๊ทธ์ธ Flow

1.  ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์ฐฝ์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด์—ฌ์ค€๋‹ค.
2. ํด๋ผ์ด์–ธํŠธ๋Š” ๋กœ๊ทธ์ธ 
3. ๋™์˜ํ•ญ๋ชฉ ์ฒดํฌํ•˜๊ณ  ์นด์นด์˜ค API ์„œ๋ฒ„์— ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋„˜๊ธด๋‹ค.
4. ์นด์นด์˜ค API ์„œ๋ฒ„๋Š” ์ „๋‹ฌ ๋ฐ›์€ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๊ณ  ์„œ๋น„์Šค ์„œ๋ฒ„์˜ Redirect URI๋กœ ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๋ฐœ๊ธ‰ํ•ด์ค€๋‹ค.
5. ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์นด์นด์˜ค API ์„œ๋ฒ„๊ฐ€ ๋กœ๊ทธ์ธ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•œ๋‹ค.

 

์šฐ๋ฆฌ ํŒ€์€ ์–ด๋””๊นŒ์ง€ ํ”„๋ก ํŠธ๊ฐ€ ํ•˜๊ณ  ๋ฐฑ์—”๋“œ๊ฐ€ ์–ด๋””์„œ๋ถ€ํ„ฐ ๋งก์•„ ํ• ์ง€ ์ •ํ–ˆ๋‹ค.

๐Ÿ“Œ ์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•  ์ ์€ ํ† ํฐ์„ ์นด์นด์˜ค ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์ง€๋งŒ, ํ† ํฐ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํ•ดํ‚น ๋‹นํ•˜๋ฉด
์‚ฌ์šฉ์ž์˜ ์นด์นด์˜ค ๊ณ„์ •์— ์žˆ๋Š” ๋ชจ๋“  ์ •๋ณด๊ฐ€ ๋‹ค ํ„ธ๋ฆด ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์นด์นด์˜ค ์„œ๋ฒ„์—์„œ ๋ฐœ๊ธ‰ ๋ฐ›์€ ์‚ฌ์ดํŠธ ์ „์šฉ ํ† ํฐ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

Frontend ์—ญํ• 

์นด์นด์˜ค๋กœ๋ถ€ํ„ฐ ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๋ฐ›๊ณ  ๋ฐ›์€ ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๋ฐฑ์—”๋“œ์— ๋„˜๊ฒจ์ค€๋‹ค.
์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๋„˜๊ธฐ๋ฉด ๋ฐฑ์—”๋“œ๋กœ๋ถ€ํ„ฐ ์‚ฌ์ดํŠธ์—์„œ ์“ธ ํ† ํฐ์„ ๋ฐœ๊ธ‰ ๋ฐ›๋Š”๋‹ค.
 

Backend ์—ญํ• 

ํ”„๋ก ํŠธ์—”๋“œ์—๊ฑฐ ์ธ๊ฐ€์ฝ”๋“œ ๋„˜๊ฒจ ๋ฐ›๊ณ , ์นด์นด์˜ค๋กœ๋ถ€ํ„ฐ ํ† ํฐ์„ ๋ฐœ๊ธ‰ ๋ฐ›๋Š”๋‹ค.
ํ•ด๋‹น ํ† ํฐ์— ๋‹ด๊ธด ์œ ์ € ์ •๋ณด๋ฅผ ํ™œ์šฉํ•ด ์‚ฌ์ดํŠธ ์ „์šฉ ํ† ํฐ์œผ๋กœ ์ƒˆ๋กœ ๋ฐœ๊ธ‰ ๋ฐ›์•„ ํ”„๋ก ํŠธ์—”๋“œ์—๊ฒŒ ๋Œ๋ ค์ค€๋‹ค.
 
 


 

๐Ÿ”‘ ์นด์นด์˜ค ๋กœ๊ทธ์ธ API ์—ฐ๋™ ์ˆœ์„œ
Kakao Developer ์„ค์ • -> ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ค์ • -> ๋กœ๊ทธ์ธ ๊ตฌํ˜„ํ•˜๊ธฐ

1. Kakao Developer ์„ค์ •

์•„๋ž˜ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด๊ฐ€์„œ ์„ค์ •
https://developers.kakao.com/console/app 
 
 

 step 1 ๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ

 
 step 2 ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ™œ์„ฑํ™”

๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ -> ์ œํ’ˆ ์„ค์ •/ ์นด์นด์˜ค๋กœ๊ทธ์ธ -> ์นด์นด์˜ค๋กœ๊ทธ์ธ ํ™œ์„ฑํ™”

 

 step 3 Web ํ”Œ๋žซํผ ๋“ฑ๋ก

๋‚˜์ค‘์— ๋ฐฐํฌํ•  ์ฃผ์†Œ๋ฅผ ์ ์œผ๋ฉด ๋œ๋‹ค.
๋ฐฐํฌํ•˜๊ธฐ ์ „์ด๊ธฐ ๋•Œ๋ฌธ์— localhost:3000 ์œผ๋กœ ์ผ๋‹จ ์„ค์ •

 

 step 4 Redirect URI ๋“ฑ๋ก

์นด์นด์˜ค ๋กœ๊ทธ์ธ ๋ฉ”๋‰ด์— ๋“ค์–ด๊ฐ€์„œ ์ถ”๊ฐ€
๊ฒฝ๋กœ ์„ค์ •์€ ๋ฐฑ์—”๋“œ์™€ ํ˜‘์˜ํ•ด์„œ ๋งž์ถ”๋ฉด ๋˜๋Š”๋ฐ, ๋‚ด๊ฐ€ ๋จผ์ € ์„ค์ •ํ•˜๊ณ  ์จ๋‹ฌ๋ผ๊ณ  ํ–ˆ๋‹ค.
โš ๏ธํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” Host ๋กœ ์ง€์ •ํ•˜๊ธฐ!

'

 step 5 ๋™์˜ํ•ญ๋ชฉ ์„ค์ •

์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ›„ ์„ค์ •ํ•œ ๋™์˜ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ -> ์ œํ’ˆ์„ค์ • -> ๋™์˜ํ•ญ๋ชฉ
 
 
 
์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•ด์ฃผ๋ฉด ์นด์นด์˜ค ๋กœ๊ทธ์ธ  API ์‚ฌ์šฉ์— ํ•„์š”ํ•œ ์„ค์ •์ด ์™„๋ฃŒ๋œ๋‹ค.
์ด์   ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ์นด์นด์˜ค ์„œ๋ฒ„์— ์š”์ฒญํ•  ๋•Œ ํ•„์š”ํ•œ ํ‚ค๋“ค์„ ํ™•์ธํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 
 

 

2. ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ค์ •

 step 1 ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญํ–ˆ์„ ๋•Œ KAKAO_AUTH_URL๋กœ ์ด๋™
 

//KakaoAuthUrl.js

export const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?
client_id=${REACT_APP_CLIENT_ID}
&redirect_uri=${REACT_APP_REDIRECT_URI}
&response_type=code`;

 
๋‚˜๋Š” ๋”ฐ๋กœ KakaoAuthUrl.jsํŒŒ์ผ์„ ๋งŒ๋“ค์–ด Kakao Auth Url์„ ๋‚ด๋ณด๋‚ด์ฃผ์—ˆ๋‹ค.
client_id ๊ฐ’์œผ๋กœ Rest API Key ๋ฅผ ๋„ฃ๊ณ  redirect_uri ๊ฐ’์œผ๋กœ Redirect URI๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
 

  //SignIn.js
  
  ...
  
  function handleLogin() {
    window.location.href = KAKAO_AUTH_URL;
  }

  ...
  
  return (
  
  ...
  
  <KakaoButton imgUrl={logoBtnImg} onClick={handleLogin} />
  )

 
์นด์นด์˜ค๋กœ ๋กœ๊ทธ์ธํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ด Url์ฃผ์†Œ๋กœ ์นด์นด์˜คํ†ก ๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ ์ด๋™๋˜๊ฒŒ ๊ตฌํ˜„ํ•ด์ค˜์•ผ ํ•œ๋‹ค.
window.location.href๋ฅผ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅธ URL๋กœ ์ด๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. 
๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋ฉด ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ™”๋ฉด์ด ๋‚˜ํƒ€๋‚˜๊ณ  ์—ฌ๊ธฐ์„œ ์นด์นด์˜ค ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๊ณ  ๋™์˜ํ•ญ๋ชฉ ์ฒดํฌํ•˜๊ณ  ๋‚˜๋ฉด
์•„๋ž˜์™€ ๊ฐ™์ด ๋นˆ ํ™”๋ฉด์ด ๋‚˜์˜จ๋‹ค. 
 

 
๋‚˜๋Š” ๊ณ„์† ์ € ๋นˆํ™”๋ฉด์—์„œ ์—๋Ÿฌ๊ฐ€ ์žˆ์—ˆ๋‹ค.
๋ฐฑ์—”๋“œ ํ†ต์‹ ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฑด์ง€ ๋ฐฑ์—”๋“œ ํŒ€์›๋ถ„์ด๋ž‘ ๊ณ„์† ์ด์œ ๋ฅผ ์ฐพ์•„๋ดค์—ˆ๋Š”๋ฐ 
์ธ๊ฐ€์ฝ”๋“œ๋Š” ๋ฐ›๋Š” ๊ฒƒ์—” ๋ฌธ์ œ๊ฐ€ ์—†์–ด๋ณด์˜€๊ณ  ๋ฃจํŠธ๋ฅผ ๊ณ„์† ๋ชป ์ฐพ๋Š”๋‹ค๊ณ  ๋‚˜์™”์—ˆ๋‹ค.
์ง€๊ธˆ ์ƒ๊ฐํ•˜๋ฉด ํ—ˆ๋ฌดํ–ˆ๋˜ ๊ฒŒ ๋ฐฑ์—”๋“œ๋ž‘ ํ†ต์‹ ํ•˜์ง€๋„ ์•Š์•˜๋Š”๋ฐ ์—„ํ•œ ๋ฐ์„œ ๋ฌธ์ œ๋ฅผ ์ฐพ์•„๋ดค๋˜ ๊ฒƒ..
๋ผ์šฐํ„ฐ ํŽ˜์ด์ง€๋ฅผ ๋ณด๋‹ˆ ์ € ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋Š”๋ฐ ์–ด๋А ์ฃผ์†Œ๋กœ ๋ณด์—ฌ์ค„์ง€ ์ •ํ•ด๋‘์ง€ ์•Š์•˜๋˜ ๊ฑฐ์˜€๋‹ค.

 
Redirect URI๋กœ ์„ค์ •ํ•ด๋‘๋‹ˆ ํ•ด๊ฒฐ๋๋‹ค.

 
 
 
 step 2 ์นด์นด์˜ค API์— ์ธ๊ฐ€ ์ฝ”๋“œ ๋ถ™์—ฌ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
 
์œ„์— ์žˆ๋Š” ๋นˆ ํ™”๋ฉด ์ฃผ์†Œ์ฐฝ์— redirect_uri ์ฃผ์†Œ ๋’ค์— ?code= ์ธ๊ฐ€์ฝ”๋“œ ๊ฐ€ ๋‚˜์˜ค๋Š”๋ฐ ์ด ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์™€์„œ
๋ฐฑ์—”๋“œ์— ๋„˜๊ฒจ์ฃผ์–ด ํ† ํฐ์„ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.
 
๋‚˜๋Š” ์ด ์ฃผ์†Œ์—์„œ ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ๋นผ๊ธฐ ์œ„ํ•ด useLocation์„ ์ผ๋‹ค.
location ์— ์žˆ๋Š” 'search'  key์— '?code= ์ธ๊ฐ€์ฝ”๋“œ'๊ฐ€ ๋‹ด๊ฒจ ์žˆ์–ด splitํ•˜์—ฌ '=' ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ๋‘๋ฒˆ์งธ ํ•ญ๋ชฉ์„ ๊ฐ€์ ธ์™”๋‹ค.

const location = useLocation();
const CODE = location.search.split('=')[1];

 
 
์นด์นด์˜ค API์— ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ  client_id, redirect_uri ๊ฐ’๊ณผ ํ•จ๊ป˜ body์— ๋‹ด์•„ ์š”์ฒญํ•œ๋‹ค.

//KakaoAuth.js

...

fetch("https://kauth.kakao.com/oauth/token", {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
      },
      body: `grant_type=authorization_code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&code=${CODE}`,
    })

 
 
 step 3 ์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์นด์นด์˜คAPI๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ํ† ํฐ์„ ๋ฐฑ์—”๋“œ์— ์ „์†ก

//KakaoAuth.js

fetch( ... )
  .then(res => res.json())
  .then(data => {
    if (data.access_token) {
      fetch("๋ฐฑ์—”๋“œ API์ฃผ์†Œ", {
        method: 'POST',
        headers: { 'Content-Type': 'application/json;charset=utf-8' },
        body: JSON.stringify({
          kakaoAccessToken: data.access_token,//์นด์นด์˜ค๋กœ๋ถ€ํ„ฐ ๋ฐœ๊ธ‰๋ฐ›์€ ํ† ํฐ์„ ๋ฐฑ์—”๋“œ๊ฐ€ ์ค€ ํ‚ค๊ฐ’์— ๋งž์ถค
          nickname: '',//์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„์„ ์“ธ ํŽ˜์ด์ง€๊ฐ€ ์žˆ์–ด์„œ ๊ฐ™์ด ์š”์ฒญ
        }),
      })

 
 
 step 4 ๋ฐฑ์—”๋“œ์—๊ฒŒ์„œ ํŒ€ ํ”„๋กœ์ ํŠธ ์‚ฌ์ดํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ „์šฉ ํ† ํฐ์„ ๋‹ค์‹œ ๋ฐ›๊ธฐ
๋ฐฑ์—”๋“œ์— ์นด์นด์˜ค ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ ๋ฐ›์€ ํ† ํฐ์„ ๋ณด๋‚ด์คฌ๋‹ค๋ฉด,
๋ฐฑ์—”๋“œ์—์„  ๊ทธ ํ† ํฐ์„ ๋ณด์•ˆ์„ ์œ„ํ•ด ์‚ฌ์ดํŠธ ์ „์šฉ ํ† ํฐ์œผ๋กœ ๋ฐ”๊พธ์–ด ๋‹ค์‹œ ๋ณด๋‚ด์ค€๋‹ค.
ํ† ํฐ์„ ๋ฐ›์œผ๋ฉด local storage ์— ์ €์žฅํ•œ๋‹ค.

//KakaoAuth.js

.then(response => response.json())
.then(result => {
  if (result.token) {
    localStorage.setItem('TOKEN', result.token);
    localStorage.setItem('username', result.nickname);
  }
});

 
 
 
KakaoAuth.js ํŒŒ์ผ ์ „์ฒด ์ฝ”๋“œ
์ธ๊ฐ€์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ† ํฐ ์š”์ฒญํ•˜๊ณ  ๋ฐœ๊ธ‰๋ฐ›์•„ ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋˜์–ด ๋กœ๊ทธ์ธ์ด ์‹คํ–‰๋˜๋Š” ๊ณณ์ด๋‹ค.
๋‚˜๋Š” ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ์ด ์ง€์—ฐ๋˜๋Š” ๊ฑธ ๋Œ€๋น„ํ•ด์„œ ์Šคํ”ผ๋„ˆ(๋กœ๋”ฉ๋ฐ”)๋ฅผ ์ถ”๊ฐ€ํ•ด์คฌ๋‹ค.

import React, { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import { PulseLoader } from 'react-spinners';
import { API } from '../../../config';

function KakaoAuth() {
  const navigate = useNavigate();
  const location = useLocation();
  const CODE = location.search.split('=')[1];

  function getKakaoToken() {
    fetch(`${API.kakaoAuthToken}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
      },
      body: `grant_type=authorization_code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&code=${CODE}`,
    })
      .then(res => res.json())
      .then(data => {
        if (data.access_token) {
          fetch(`${API.kakaoLogin}`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json;charset=utf-8' },
            body: JSON.stringify({
              kakaoAccessToken: data.access_token,
              nickname: '',
            }),
          })
            .then(response => response.json())
            .then(result => {
              if (result.token) {
                localStorage.setItem('TOKEN', result.token);
                localStorage.setItem('username', result.nickname);
                alert('๋กœ๊ทธ์ธ ์„ฑ๊ณตํ–ˆ์–ด์š”!');
                navigate('/');
              }
            });
        } else {
          alert('๋‹ค์‹œ ํ•œ ๋ฒˆ ๋กœ๊ทธ์ธํ•ด์ฃผ์„ธ์š”!');
          navigate('/signin');
        }
      });
  }

  useEffect(() => {
    getKakaoToken();
  }, []);

  return (
    <Spinner>
      <PulseLoader color="#6200EE" margin={8} size={20} />
    </Spinner>
  );
}

export default KakaoAuth;

const Spinner = styled.div`
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
`;

 
 

๐Ÿ”‘ .envํŒŒ์ผ๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ํŒŒ์ผ ๊ณต์œ 

๊ทธ๋ฆฌ๊ณ  client_id, redirect_uri๋Š” ๋ณด์•ˆ์˜ ์ด์œ ๋กœ .env ํŒŒ์ผ์— ์ž‘์„ฑํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.
๊นƒํ—™์— ๊ทธ๋ƒฅ ์˜ฌ๋ฆฌ๋ฉด client_id, redirect_uri๋ฅผ ๋‹ค ๊ณต์œ ํ•˜๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„ํ—˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
 
React ๋Š” ์•ž์— REACT_APP_๋ณ€์ˆ˜๋ช… ์œผ๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค.

//.env.js

REACT_APP_CLIENT_ID = ...
REACT_APP_REDIRECT_URI = ...

 
๋”ฐ๋ผ์„œ client_id, redirect_uri ๊ฐ€ ์“ฐ์ธ ๊ณณ์—๋„ ์•„๋ž˜์™€ ๊ฐ™์ด process.env.REACT_APP_๋ณ€์ˆ˜์ด๋ฆ„ ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

//KakaoAuth.js

body: `grant_type=authorization_code&client_id=${process.env.REACT_APP_CLIENT_ID}&redirect_uri=${process.env.REACT_APP_REDIRECT_URI}&code=${CODE}`,