์นด์นด์ค๊ณ์ ์ ์ด์ฉํ ์์ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ์๋ค
PosePicker(ํฌ์ฆํผ์ปค) ๊ฐ๋ฐ ์๋ฆฌ์ฆ
- ์นด์นด์ค ์์ ๋ก๊ทธ์ธ ํ๋ก ํธ์๋์์ ๊ตฌํํ๊ธฐ
- ๋ก๊ทธ์ธ ์ ๋ณด ์ ์ญ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ(recoil)
- ๋ก๊ทธ์์๊ณผ ์๋น์ค ํํด ๊ตฌํ
- ์๋ฒ ํต์ ์ฉ ํค๋์์ ์์ธ์ค ํ ํฐ ๊ด๋ฆฌ(axios)
- ์ธ์ ๋ง๋ฃ์ ์๋ ๋ก๊ทธ์์ ๊ตฌํ(interceptor)
1. ๋ก๊ทธ์ธ ๋ฒํผ์ ๋๋ฅด๋ฉด ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐ๋ ๋งํฌ๋ก ์ ์ํ๋ค
์ด๋ ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐ๋ ๋งํฌ์๋ Redirect URI๊ฐ ํฌํจ๋์ด์๋ค
2. ๋ก๊ทธ์ธ์ด ์๋ฃ๋๋ฉด ์๊น ํฌํจ๋์ด ์๋ Redirect URI๋ก ์๋์ผ๋ก ์ด๋ํ๋ฉฐ ์ด๋ ์ธ๊ฐ์ฝ๋๊ฐ ๊ฐ์ด ์จ๋ค.
์ธ๊ฐ์ฝ๋๋ url์ ์ฟผ๋ฆฌ ํํ{RedirectUri}?code={์ธ๊ฐ์ฝ๋}
๋ก ์จ๋ค
3. ํด๋น ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐฑ์๋์๊ฒ ๋ณด๋ด์ฃผ๋ฉด ๋ก๊ทธ์ธ ์๋ฃ
๋ณธ ํ๋ก์ ํธ๋ฅผ ํฌํจํ ์ผ๋ฐ์ ์ธ ๋ก๊ทธ์ธ์์๋ API์ ์ธ๊ฐ์ฝ๋๋ฅผ ํฌํจํด์ ์์ฒญํ๋ฉด ๋ก๊ทธ์ธ ์๋ฃ๋ ์ ๋ณด๋ฅผ ๋ฐํํ์ฌ ๋ณด๋ด์ค๋ค.
- ๋ก๊ทธ์ธ ๋ฒํผ์ ๋๋ฅด๋ฉด ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐ๋ ๋งํฌ๋ก ์ ์ํ๋ค
์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐ๋ ๋งํฌ๋ ๊ณต์๋ฌธ์์ ๋์์๋ค.
ํ์๋ง ์ ๋ง์ถฐ์ ๋ฐ๊ธํ ์๋ฒํค์ ๋ฆฌ๋ค์ด๋ ํธ uri๋ฅผ ํฌํจ์์ผ์ฃผ์
const KAKAO_AUTHORIZE = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_SERVER_KEY}&redirect_uri=${KAKAO_REDIRECT_URI}&response_type=code`;
- ๋ก๊ทธ์ธ์ด ์๋ฃ๋๋ฉด ์๊น ํฌํจ๋์ด ์๋ Redirect URI๋ก ์๋์ผ๋ก ์ด๋ํ๋ฉฐ ์ด๋ ์ธ๊ฐ์ฝ๋๊ฐ ๊ฐ์ด ์จ๋ค.
์ธ๊ฐ์ฝ๋๋ url์ ์ฟผ๋ฆฌ ํํ{RedirectUri}?code={์ธ๊ฐ์ฝ๋}
๋ก ์จ๋ค.
์ฌ๊ธฐ์๋ {๋๋ฉ์ธ}/auth?code={์ธ๊ฐ์ฝ๋}
ํํ
๋ฆฌ๋ค์ด๋ ํธ ๋ ํ์ด์ง์์๋ useSearchParams()๋ฅผ ์ด์ฉํ์ฌ ํ์ฌ url์์ 'code'์ ํด๋นํ๋ ๊ฐ์ธ ์ธ๊ฐ์ฝ๋๋ฅผ code ๋ณ์์ ์ ์ฅํ๋ค.
ํด๋น ์ธ๊ฐ์ฝ๋๋ก ๋ก๊ทธ์ธapi๋ก ๋ก๊ทธ์ธ์ ์งํํ ํ ๊ฒฐ๊ณผ๋ก ๋ฐ์ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์ ์ญ ์ํ๋ก ์ ์ฅํ ํ ํ์ด์ง๋ฅผ ์ด๋ํ๋ฉด ๋. (์ ์ญ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ์์ ๋ณธ ๊ธ ์๋์ ๊ธฐ๋ก)
- ํด๋น ์ธ๊ฐ์ฝ๋๋ฅผ ๋ฐฑ์๋์๊ฒ ๋ณด๋ด์ฃผ๋ฉด ๋ก๊ทธ์ธ ์๋ฃ
๋ณธ ํ๋ก์ ํธ๋ฅผ ํฌํจํ ์ผ๋ฐ์ ์ธ ๋ก๊ทธ์ธ์์๋ API์ ์ธ๊ฐ์ฝ๋๋ฅผ ํฌํจํด์ ์์ฒญํ๋ฉด ๋ก๊ทธ์ธ ์๋ฃ๋ ์ ๋ณด๋ฅผ ๋ฐํํ์ฌ ๋ณด๋ด์ค๋ค.
๋ฐฑ์๋์ ๋ก๊ทธ์ธ api (์ฌ๊ธฐ์๋ /users/kakao?code={์ธ๊ฐ์ฝ๋}
์ ํต์ ํด์คฌ๋ค.
๋ก๊ทธ์ธ api๋ฅผ ์์ฒญํ๋๋ฐ ๋ฌ๋์์ด ๋ฆฌ๋ค์ด๋ ํธ uri๋ฅผ ๊ฐ์ด ๋ณด๋ด์ฃผ๋๊ฑด ์๋์ ๊ฐ์ ์ํ์ฐฉ์ค๊ฐ ์์๋ค
์์
๋ก๊ทธ์ธ API๋ฅผ ๋ถ์ด๋ ๊ณผ์ ์์ ์๊พธ 500์๋ฌ๊ฐ ๋ด๋ค
์๊ณ ๋ณด๋ ์์ธ์ ๋ฐฑ์๋์ชฝ์์ Redirect URI๋ฅผ ํ๋๋ก ์ค์ ํด๋จ๊ธฐ ๋๋ฌธ์ด์๋ค.
์ฆ, ๋ฐฑ์๋๊ฐ ์ค์ ํ URI์ธ ํ๋ก๋์ ๋งํฌ๊ฐ ์๋ ๋ก์ปฌ(localhost:3000)์ด๋ develop(๋ณธ ํ๋ก์ ํธ๋ develop๊ณผ main๋ธ๋์น๊ฐ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ๋ฐฐํฌ๋์ด์๋ค)์์ ๋ณด๋ด๋ฉด KOE006์๋ฌ(๋ฆฌ๋ค์ด๋ ํธ ๋ฏธ์ค์ ์ค๋ฅ)๊ฐ ์๊ฒจ๋ฒ๋ฆฌ๊ณ ์ด ์ค๋ฅ๋ฅผ ๋ฐ์ ๋ฐฑ์๋์์๋ 500์๋ฌ๋ฅผ ํ๋ก ํธ์๋์๊ฒ ๋ณด๋ด๋ ์ํฉ์ด์๋ค.
๋งค๋ฒ ๋ฐฑ์๋์๊ฒ ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ฐ๊ฟ๋ฌ๋ผ๊ณ ์์ฒญํ ์๋ ์์ผ๋ ํ์ฌ ํ๋ก ํธ๊ฐ ์ฌ์ฉํ๋ ๋ฆฌ๋ค์ด๋ ํธ uri๋ค์ ํ์ฉํด๋ฌ๋ผ๊ณ ๋ถํ๋๋ ธ๋๋ฐ
์๋ ๊ฒ ๋๋ฉ์ธ์ ๋งค๋ฒ ๋ถ๊ธฐ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ๊พธ์ จ๋ค๊ณ ์ฝ๋๋ฅผ ๋ณด๋ด์ฃผ์ จ๋ค.
์ด ํํ๋ ๋ฐฑ์๋์๊ฒ๋ ํ๋ก ํธ์๊ฒ๋ ํ์ฅ์ฑ์ ๊ณ ๋ คํ ์ ์๋ ๋์ ๋ฐฉ์์ด๋ผ๊ณ ์๊ฐ๋์๊ณ , ์์ redirect uri๋ฅผ ํ๋ก ํธ์์ ํด๋น api์ ํต์ ํ ๋ ๋ณด๋ด์ ๋ฐฑ์๋๋ ํ๋ก ํธ์๋์๊ฒ ๋ฐ์ RedirectURI๋ฅผ ๊ทธ๋๋ก ์ค์ ํ๋ ๋ฐฉ์์ ์ด๋จ์ง ์ ์๋๋ฆฌ๊ณ ํฉ์ํ์๋ค.
๊ทธ๋ ๊ฒ ํ๋ก ํธ๋ ๋ก๊ทธ์ธapi๋ก ํต์ ํ ๋ ์ธ๊ฐ์ฝ๋ ๋ฟ๋ง ์๋๋ผ ๋ฆฌ๋ค์ด๋ ํธ uri๋ ํฌํจ์ํค๊ฒ ๋์๋ค.
์ด ๋ฐฉ๋ฒ์ผ๋ก ์ด์ ์ ๋ฐฑ์๋์ ์ ํด๋์ ๊ฒฝ๋ก๋ก ํ๋ก ํธ์ ๋ฆฌ๋ค์ด๋ ํธ ๊ฒฝ๋ก๋ฅผ ๋ง์ถฐ์ผํ๋ ๋ณต์กํ ์ํฉ๋ ํผํ ์ ์์๋ค
Before & After
๋น์ ๋ฐค์ ๊ณ ๋ฏผํ๋ค๊ฐ ํด๊ฒฐํ๊ฒ ๋๋ฌด ๊ธฐ๋ป์ ๋์ฝ ๋ํ ์ผ๋ถ๋ฅผ ์บก์ณํ์๋ค์ผ๋ฐ์ ์ธ ๋ก๊ทธ์ธapi๋ ๋ก๊ทธ์ธ์ ์ฑ๊ณตํ๋ฉด ์ ์ ๋๋ค์๊ณผ ์ด๋ฉ์ผ ์ฃผ์, ์์ธ์ค ํ ํฐ์ ํฌํจํ ํ ํฐ ์ ๋ณด๋ฅผ ํฌํจํ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๋ฐํํด์ค๋ค.
localStorage.setItem('accesstoken', response.token.accessToken);
์๋ฒ ํต์ ์ค ํ ํฐ์ด ํ์ํ ํต์ ์๋ ํค๋์ ์๋์ผ๋ก ์์ธ์คํ ํฐ์ ํฌํจํ๋๋ก ํ ํฐ์ ๋ฐ๋ก ๋ก์ปฌ์คํ ๋ฆฌ์ง์ ์ ์ฅํด์คฌ๋ค.
๋ณด์์ด ๊ฒฝ์
์ค๋ฝ์ง๋ง ๋คํํ ์๋ฒ์ชฝ์์ OAuth๋ก ํ ํฐ ๋ง๋ฃ์ ๊ฐ๋
์ ์ ์ฉํด์คฌ๋ค
๊ทธ ์ธ์ ๋ค๋ฅธ ํ์ด์ง์์ ๋ก๊ทธ์ธ ๋ถ๊ธฐ์ฒ๋ฆฌ๋ ์ ์ ์ ๋ณด๋ฅผ ํ์ํ๊ธฐ ์ํด ํ์ํ ์ ์ ๋ฐ์ดํฐ๋ค์ Recoil์ ์ด์ฉํ์ฌ ์ ์ญ์ผ๋ก ๊ด๋ฆฌํ๋ค
recoil์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ผ ์ค์น๊ฐ ํ์ํ๋ค.
์๊น ๋ณธ ๋ก๊ทธ์ธ ํ์ด์ง์ ์ฝ๋๋ฅผ ๋ค์๋ณด์
์๋ฒ๊ฐ ๋ฐํํด์ค ๋ก๊ทธ์ธ ์ ๋ณด ์๋ต์ setUser๋ก ๋ฃ์ด์ฃผ๋ ๋ชจ์ต์ด ๋ณด์ธ๋ค.
Recoil๋ก userAtom์ ์ ์ํด์ฃผ๊ณ , ์ด ์ํฐ๊ณผ ๊ด๋ จ๋ ๋ฉ์๋๋ค์ useUserState๋ผ๋ ํ ์ ๊ตฌํํด๋๋ค.
์ฌ์ค ๋ค๋ฅธ ํ์ด์ง์์ ๋ฐ๋ก useRecoilValue๋ useSetRecoilState๋ฅผ ์ฌ์ฉํด๋ ๋์ง๋ง.. ๊ฐ์ธ์ ์ผ๋ก ํน์ ์ํฐ๊ณผ ๊ด๋ จ๋ ์์ ๋ค์ ํ ํ์ผ์ ํ ํ ์์ ๋ชจ์๋๋๊ฑธ ์ ํธํด์ ๋ ์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์ง ๊ฑฐ๋ค. ๊ฐ์ ์ทจํฅ์ ๋ง๊ฒ ์์ฑํ์
์ด๋ฐ์์ผ๋ก ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ userState ํ ์ ์ฌ์ฉํด์ ์ ์ญ์ํ์ธ ์ ์ ์ ๋ณด์ ์ ๊ทผํ๊ณ ํ์ฉํ ์ ์๋ค.
๊ทผ๋ฐ ์ด๋ ๊ฒ recoil๋ก ๊ด๋ฆฌํ๋ ์ ์ญ์ํ๋ ํ๋ฌดํ๊ฒ๋ ์๋ก๊ณ ์นจ ํ๋ฒ์ ๋ ์๊ฐ๋ฒ๋ฆฐ๋ค.. NextJS์ ๊ฒฝ์ฐ ํ์ด์ง๋ฅผ ๋ฐ๊ฟ๋๋ง๋ค ์๋ก๊ณ ์นจ๋๊ธฐ ๋๋ฌธ์ ์ด์ ๋ํ ๋์์ด ํ์ํ๋ค.
recoil-persist ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด์ userAtom์ persistAtom์ผ๋ก ์ค์ ํด์ฃผ์๋ค.
๋ก๊ทธ์์๊ณผ ์๋น์ค ํํด์ ๊ฒฝ์ฐ๋ ๋ก๊ทธ์ธ๊ณผ ๋น์ทํ๊ฒ ๊ตฌํํ๋ฉด๋๋ค.
๋์ ๊ฒฝ์ฐ ๋ก๊ทธ์์์ด๋ผ๋ ์ก์ ์ ํจ์๋ก ์ฌ์ฉํ๊ธฐ ๋ณด๋ค๋ ๋ก๊ทธ์ธ๊ณผ ๋์ผํ๊ฒ ๋ฆฌ๋ค์ด๋ ํธ ํ์ด์ง๋ฅผ ๋ง๋ค์๋ค.
๋ก๊ทธ์์ ๋ฒํผ์ ๋๋ฅด๋ฉด /auth/logout
ํ์ด์ง๋ก ์ด๋๋๊ณ ํด๋น ํ์ด์ง์์ ๋ก๊ทธ์์ ์์
์ ์งํํ๋ค
์ฌ๊ธฐ์ ๋ก๊ทธ์์ ์์ ์
์ด ๋ชจ๋ ๊ณผ์ ์ ํฌํจํ๋ค
์๊ฐ๋ณด๋ค ๊น๋ํ๊ณ ์์ค ์๋น์ค์ ์ ์ฌํ๊ฒ ์๋ํ๋ค. ์๋น์ค ํํด ํ๋ก์ฐ๋ ํ์ด์ง๊ฐ ์ถ๊ฐ๋์์ ๋ฟ ๋ก์ง์ ๋๊ฐ๋ค.
์์์ ๋ก์ปฌ์คํ ๋ฆฌ์ง์ ์ถ๊ฐํ ์์ธ์คํ ํฐ์ ์๋ฒํต์ ์์ ํจ์จ์ ์ด๊ฒ ํ์ฉํด๋ณด์
์๊พธ Unauthorized์๋ฌ๊ฐ ๋ ์ ํ์ธํด๋ณด๋ ํ ํฐ์ ํ์์ ์๋ ค์ฃผ์ง ์๊ณ ๋ ๋ค ์ก์ธ์คํ ํฐ๋ง ๋ณด๋ด์ ์๊ธฐ๋ ์ค๋ฅ์๋ค.
Bearer์ ์์ธ์คํ ํฐ ์์ ์ถ๊ฐํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฐ์์ค๋๋ผ
Bearer์ ๋ถ์ฌ์ผํ๋ ์ด์ ์ ์์ธ์คํ ํฐ์ ์ข ๋ฅ๋ ์ด ๊ธ์ ์ฐธ๊ณ ํ์
์ด์ ์๋ฒํต์ ์ ํ ๋ ์๋์ฒ๋ผ ํค๋์ ์์ธ์คํ ํฐ์ ์ถ๊ฐํ์ฌ ๋ณด๋ด์ค ์ ์๋ค.
๊ทผ๋ฐ.. ๋ก๊ทธ์ธ์ด ํ์ํ ๊ธฐ๋ฅ๋ค์ ์ฐ์ด๋, ์ฆ ์์ธ์คํ ํฐ์ ํฌํจ์์ผ์ผ ํ api๊ฐ ์์ฃผ ๋ง์๋ฐ ๊ทธ ๋ชจ๋ api์ ์ ๋ ๊ฒ ํ๋ํ๋ ์์ธ์คํ ํฐ์ ํฌํจ์ํค๊ณ ์ถ์ง ์๋ค.
๊ทธ๋ฅ ๊ธฐ๋ณธ์ ์ผ๋ก ํค๋์ ์์ธ์คํ ํฐ์ด ์ธํ ๋์ด ์์ผ๋ฉด ํธํ ๊ฒ ๊ฐ๋ค.
axios.create()๋ฅผ ์ด์ฉํ์ฌ ์๋์ฒ๋ผ ์ธ์คํด์ค๋ฅผ ์ปค์คํ
ํด์ฃผ์.
baseURL๋ ์ธํ
ํ ์ ์์ด์ ์ด์ api๊ฒฝ๋ก๋ baseURL ์ค๋ณต ์์ด ์ธ ์ ์๋ค.
์ปค์คํ ์ธ์คํด์ค๋ก ์ฌ๋ฌ๊ฐ์ง๋ฅผ ์ค์ ํ ์ ์์ง๋ง ๋๋ getAccesstoken()ํจ์๋ฅผ ์ด์ฉํด์ ๋ก์ปฌ์คํ ๋ฆฌ์ง์์ ์์ธ์คํ ํฐ์ ๊บผ๋ด๊ณ ์ด ํ ํฐ์ interceptors๋ก ๊ธฐ๋ณธ ํค๋์ ์ถ๊ฐํด์ฃผ์๋ค.
์ฐธ๊ณ ๋ก ํฌ์ฆํผ์ปค ํ๋ก์ ํธ๋ ๋ก๊ทธ์ธ ์์ด(์ฆ ์์ธ์คํ ํฐ ์์ด๋) ํต์ ํ๋ Api๋ ๊ฝค ์์ด์ ์ด api๋ค์ ๋ฐ๋ก ์ธ์คํด์ค๋ฅผ ์ ์ํด์ฃผ์๋ค (publicApi์ privateApi๋ก ๋๋จ)
์์์ ์ฌ์ฉํ axiosInstance๋ฅผ ์ ์ธํ ํ๋ฉด ํด๋น ์ธ์คํด์ค๋ก ์๋ฒ ํต์ ์ ํ ๋ ๋ง๋ค ํน์ ์๋ต์ ๋ํด ํน์ ํ๋์ด ๊ฐ๋ฅํ๋ค
์ด๋ ๊ฒ ํด๋น ์ธ์คํด์ค๋ฅผ ํตํ ์๋ฒํต์ ์์ ์๋ฌ๊ฐ ๋จ๋ฉด alert์ฐฝ์ด ๋จ๊ฒ ํ ์ ์๊ณ , ๊ทธ ์์์ ํน์ ์๋ฌ(์ฌ๊ธฐ์๋ ์ธ์ ๋ง๋ฃ์ธ 415์๋ฌ)๋ฅผ ๋ถ๊ธฐ์ฒ๋ฆฌํด์ ๋ค๋ฅธ alert์ฐฝ์ ๋์์ฃผ๊ณ ๋ก๊ทธ์์์ ์๋์ผ๋ก ์งํํ ์ ์๋ค.
์ฐธ๊ณ ๋ก interceptors.request.use์ interceptors.response.use๊ฐ ๋ค๋ฅด๋ ์ ๊ตฌ๋ถํด์ ์ฐ์
axios.interceptors.request.use(
(config) => {
...
return config;
},
(error) => {
...
return Promise.reject(error);
}
);
// ์์ ๋ค๋ฆ
axios.interceptors.response.use(
(config) => {
...
return config;
},
(error) => {
...
return Promise.reject(error);
}
);
๋ ๋ถ๋ช
๋ฆด๋ฆฌ์ฆ๋
ธํธ๋ฅผ ์์ฑํ๋ คํ๋๋ฐ..
์ด์ฉ๋ค ์ด๋ฐ ์ ๋ณด์ฑ ํฌ์คํ
์..