Trouble Shooting - accessToken

Doodreamยท2021๋…„ 10์›” 9์ผ
1

ChawChaw - ํ”„๋กœ์ ํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
5/8
post-thumbnail

๐Ÿ— ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ

๋กœ๊ทธ์ธ ๋ณด์•ˆ์„ ์œ„ํ•ด์„œ jwt๋กœ ํ† ํฐ์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ์ธ์ฆํ•˜๋Š” ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. accessToken ํ•˜๋‚˜๋กœ๋งŒ์œผ๋กœ๋Š” ๋ณด์•ˆ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ refreshToken์ด๋ผ๋Š” ๊ฒƒ์œผ๋กœ ์ด์ค‘๋ณด์•ˆ์„ ํ•ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ ์‹œ๋„

์„œ๋ฒ„์—์„œ๋Š” jwtํ† ํฐ์„ ๋ฐœํ–‰ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ์ž๋ฅผ ๊ตฌ๋ถ„๊ฐ€๋Šฅํ•œ ์ธ์ฆ์ •๋ณด๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ์ธ์ฆ ๋งŒ๋ฃŒ๊ธฐ๊ฐ„๋“ฑ์˜ ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ„ ํ† ํฐ์„ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์•”ํ˜ธํ™”๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ํ•˜๋ฉด jwtํ† ํฐ์„ ๋‘๊ฐ€์ง€ ์ƒ์„ฑํ›„ refreshToken๊ณผ accessToken์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ €์žฅํ•œ ํ›„ ์ €์žฅํ•œ accessToken์„ ๊ฐ€์ง€๊ณ  api ์š”์ฒญ์— ๋Œ€ํ•œ ๋ณด์•ˆ ์ •๋ณด๋กœ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

accessToken ๋งŒ๋ฃŒ์‹œ

accessToken์€ ๋ณดํ†ต 30๋ถ„ ๋‹จ์œ„๋กœ ๋งŒ๋ฃŒ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž๊ฐ€ api๋ฅผ ์š”์ฒญํ•˜๋ฉด ๊ถŒํ•œ๋งŒ๋ฃŒ response๋ฅผ ๋ฐ›๊ฒŒ ๋ ์‹œ ์žฌ๋ฐœ๊ธ‰ api๋ฅผ ๋ณด๋‚ด๋„๋ก ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ accessToken๊ณผ refreshToken์„ ๋ณด๋‚ด๋ฉด ์„œ๋ฒ„์—์„œ refreshToken์„ ์ธ์ฆํ•˜๊ณ  accessToken์„ ์žฌ๋ฐœ๊ธ‰ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋•Œ refreshToken์˜ ์ธ์ฆ๊ธฐํ•œ์€ 30์ผ ์ž…๋‹ˆ๋‹ค.

refreshToken ๋งŒ๋ฃŒ์‹œ

refresh Token์ด ๋งŒ๋ฃŒ๋˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ ์žฌ๋กœ๊ทธ์ธ์„ ํ•˜๋„๋ก ์œ ๋„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๋ฌผ๋ก  ์‚ฌ์šฉ์ž๊ฐ€ 30์ผ ์ด๋‚ด์— ๋‹ค์‹œ ๋กœ๊ทธ์ธ์„ ํ–ˆ๋‹ค๋ฉด refreshToken๋„ ์žฌ๋ฐœ๊ธ‰์ด ๋˜๋‹ˆ ์ƒ๊ด€์—†์ง€๋งŒ 30์ผ ์ด์ƒ ๋กœ๊ทธ์ธ์„ ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์‚ฌ์šฉ์ž๋Š” ๋‹ค์‹œ ๋กœ๊ทธ์ธ์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ € ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณด์•ˆ์ทจ์•ฝ์ ๋“ค์ด ์–ด๋–ค ๊ฒƒ๋“ค์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค.

๐Ÿ” ๋ณด์•ˆ์ฒ˜๋ฆฌ ์ทจ์•ฝ์ 

์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ณด์•ˆ์— ๋Œ€ํ•œ ์ทจ์•ฝ์ ์€ ํฌ๊ฒŒ 2๊ฐ€์ง€ ์ž…๋‹ˆ๋‹ค. XSS, CSRF

XSS

๊ณต๊ฒฉ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ (์›น๋ธŒ๋ผ์šฐ์ €์—์„œ) javascript ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•ด์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋‚ด๋ถ€์˜ input ์ด๋‚˜ ์›น๋ธŒ๋ผ์šฐ์ €์˜ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ๊ฐ€๋กœ์ฑ„ ์„œ๋ฒ„์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ถŒํ•œ์„ ์†์ด๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์„œ๋ฒ„๋‚˜ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ์ด์ƒ์„ ๊ฐ์ง€ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์ฝ”๋“œ์ธ์ฒ™ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

CSRF

์ด๊ฒฝ์šฐ๋Š” ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ์ฝ”๋“œ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค๋ฉด ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์—์„œ๋„ ์„œ๋ฒ„์— api ์ฝœ์„ ๋ณด๋‚ผ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์•…์šฉํ•œ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
๊ณต๊ฒฉ์ž๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์—์„œ ์šฐ๋ฆฌ ์„œ๋ฒ„์— api๋ฅผ ์š”์ฒญํ•ด์„œ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต์„ ํ•˜๋Š” ๊ฒฝ์šฐ ์ž…๋‹ˆ๋‹ค. ์š”์ฆ˜ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์‚ฌ์‹ค https ํ†ต์‹ ์œผ๋กœ ๋ณด์•ˆ์„ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๋“œ๋ฌธ๊ฒฝ์šฐ์ด๊ณ  ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ CORS ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๋น„๊ต์  ์•ˆ์ „ํ•œ ๊ฒฝ์šฐ ์ž…๋‹ˆ๋‹ค.

์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๋•Œ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” localStorage, cookie ๋“ฑ์— ์ธ์ฆ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š”๋ฐ ๊ฐ๊ฐ Next js์—์„œ ์–ด๋–ค๊ฒƒ์ด ์ด์Šˆ์˜€๋Š”์ง€ ์ด์•ผ๊ธฐํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜„๊ณผ์ •

ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ์ฃผ์š” ์ด์Šˆ๊ฐ€ ์–ด๋””์— accessToken๊ณผ refreshToken์„ ์ €์žฅํ•˜๋Š๋ƒ์˜€์Šต๋‹ˆ๋‹ค.

refreshToken์€ ์„œ๋ฒ„์—์„œ ์ฟ ํ‚ค๋กœ httponly, secure ์„ค์ •์„ ํ•ด์„œ ์ „์†กํ•ด์ฃผ๊ธฐ์— ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ๋”ฐ๋กœ ๋งŒ์งˆ ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

httponly ์„ค์ •์€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ฟ ํ‚ค๋ฅผ ๋”ฐ๋กœ ๋งŒ์งˆ์ˆ˜ ์—†๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฟ ํ‚ค๋ฅผ ๊ฑด๋“ค์ด๋Š” ๊ถŒํ•œ์„ ์ฃผ์ง€ ์•Š์Œ์œผ๋กœ์„œ XSS ๊ณต๊ฒฉ๋ฐฉ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

secure ์„ค์ •์€ https ํ†ต์‹ ์—์„œ๋งŒ ์ฟ ํ‚ค๋ฅผ ๋ณด๋‚ผ์ˆ˜ ์žˆ๊ฒŒํ•˜๋Š” ์„ค์ •์œผ๋กœ์„œ CORS ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” CSRF ๊ณต๊ฒฉ๋ฐฉ์–ด๋ฅผ ํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

accessToken๋ฅผ ์–ด๋””์— ์ €์žฅํ•˜๋ƒ ์ธ๋ฐ ๊ฐ๊ฐ ์•Œ์•„๋ด…์‹œ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ accessToken์„ react์—์„œ ๋กœ์ปฌ ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•œ๋‹ค๋ฉด react์—์„œ JSX ๋ณ€ํ™˜๊ณผ์ • ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ € ์™ธ๋ถ€์—์„œ ๊ด€๋ จ ๋กœ์ง์„ ์ฝ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— XSS ๊ณต๊ฒฉ๋ฐฉ์–ด๊ฐ€ ์–ด๋Š์ •๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” ๋‹ค์‹œ ์„œ๋ฒ„์—์„œ ์• ์ดˆ์— refreshToken ์ฒ˜๋Ÿผ cookie์— ๋„ฃ์–ด์„œ ๋ณด๋‚ด์ฃผ๋Š๋ƒ ์„œ๋ฒ„์—์„œ JSON ํŒŒ์ผ๋กœ accessToken์„ ๋ฐ›์•„์„œ ๋‹ค์‹œ ๋ธŒ๋ผ์šฐ์ €์—์„œ accessToken์„ ์ฟ ํ‚ค์— ๋„ฃ๋Š๋ƒ ์ž…๋‹ˆ๋‹ค.

  1. ์„œ๋ฒ„์—์„œ ์ฟ ํ‚ค์— ๋„ฃ์–ด ๋ณด๋‚ด์ฃผ๋Š” ๊ฒฝ์šฐ
  • ์ด๋ ‡๊ฒŒํ•˜๋ฉด httponly ์„ค์ •์„ ํ•ด์ œํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. accessToken์„ ํ”„๋ก ํŠธ์—์„œ์ฝ๊ฑฐ๋‚˜ ์‚ฌ์šฉํ• ์ˆ˜๊ฐ€ ์—†๊ธฐ๋•Œ๋ฌธ์— ์„ค์ •์„ ํ•ด์ œํ•˜๋Š”๋ฐ ์ด๋Š” XSS ๊ณต๊ฒฉ์— ์˜ํ•ด accessToken์ด ํƒˆ์ทจ ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  1. ์„œ๋ฒ„์—์„œ JSON ํŒŒ์ผ๋กœ accessToken์„ ๋ณด๋‚ด์ฃผ์–ด ํ”„๋ก ํŠธ์—์„œ cookie์— ์ €์žฅํ•  ๊ฒฝ์šฐ
  • ์ด๊ฒฝ์šฐ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ api๋ฅผ ์„œ๋ฒ„๋กœ ๋ณด๋‚ผ๋•Œ๋งˆ๋‹ค ์ง€์†์ ์œผ๋กœ ์ฟ ํ‚ค์— ๊ฐ™์ด ๋„ฃ์–ด์ ธ ๋ณด๋‚ด์ง€๋Š”๋ฐ api ์š”์ฒญํ—ค๋”๊ฐ€ ์ปค์ง€๋Š” ๋‹จ์ ์ด ์žˆ๊ณ  document.cookie ๋กœ accessToken์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด ์™ธ๋ถ€์—์„œ XSS ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•ด์ง€๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋‹จ์ ์€ react ๋‚ด๋ถ€์—์„œ ์ธ์ฝ”๋”ฉํ•จ์œผ๋กœ์„œ ๋ณด์™„ํ•  ์ˆ˜ ์žˆ์œผ๋‚˜ ๊ถ๊ทน์ ์ด์ง„ ์•Š์Šต๋‹ˆ๋‹ค.

  • next js์—์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด accessToken์„ ์žฌ ์ธ์ฆํ•˜๋Š” ํ˜•ํƒœ๋กœ ๊ตฌํ˜„์„ ํ•˜๋Š”๋ฐ ์žˆ์–ด ์ฟ ํ‚ค๋ฅผ ์ฝ์„๋•Œ react-cookie ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ์ธ์ฝ”๋”ฉ์„ํ•˜๋Š”๋ฐ ์ด๊ณผ์ •์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ accessToken์ด ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ฐ˜์˜๋˜์ง€ ์•Š์•„ ์ด์ „ accessToken์œผ๋กœ api๋ฅผ ๋ณด๋‚ด๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•˜๋ฉด accessToken์„ ์ƒˆ๋กœ ๋ฐ›๋Š”๋ฐ ๊ทธ์ „์— ์›นํŽ˜์ด์ง€์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์‹คํ–‰๋˜์ž๋งˆ์ž ์‹คํ–‰ํ•˜๋Š” api๋“ค์ด ๋จผ์ € ์‹คํ–‰๋˜์–ด ์ด์ „์˜ accessToken์œผ๋กœ ์ธ์ฆ๋˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋”๊ตฐ๋‹ค๋‚˜ react-cookie๋Š” ๋กœ์ปฌ ๋ณ€์ˆ˜๋กœ์„œ ๋™์ž‘ํ•˜๊ธฐ์— ์ฟ ํ‚ค๊ฐ€ ๋ฐ”๋€Œ๊ณ ๋„ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ ๋•Œ ์ด์ „์˜ ์ฟ ํ‚ค๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

const [cookies, setCookie, removeCookie] = useCookies(["accessToken"]);

const grantRefresh = async () => {
  
    console.log("grantRefresh", cookies.accessToken);
    const response = await axios
      .post(
        "/users/auth/refresh",
        {},
        {
          headers: {
            "Content-Type": "application/json",
            Authorization: cookies.accessToken,
            Accept: "application/json",
          },
        }
      )
      .catch((err) => {
        console.error(err, "grant access Token Fail");
        console.log(err, "grant access Token Fail");
        return err.response;
      });
}

๋”ฐ๋ผ์„œ ํ•จ์ˆ˜์˜ ๋™์ž‘์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ”๋€ accessToken์„ ๋ฐ˜์˜ํ•˜๋ ค๋ฉด ์ง์ ‘ localStorage๋‚˜ ์ฟ ํ‚ค์—์„œ ๊ฐ’์„ ์ฝ์–ด์•ผ ํ•˜๋Š”๋ฐ ๋‘˜๋‹ค ์™ธ๋ถ€์—์„œ accessToken์„ ์ง์ ‘๋ณด๋Š” ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

accessToken - localStorage

ํ•˜์ง€๋งŒ react์—์„œ๋Š” ๋ณ€์ˆ˜๋ฅผ escapeํ•ด์ฃผ๊ณ  jsx ๋ณ€ํ™˜๊ณผ์ •์—์„œ html์˜ ๋ฌธ์ž์—ด์„ ๋ชจ๋‘ escape ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— xss ๊ณต๊ฒฉ์— ๋Œ€ํ•œ ์œ„ํ—˜์„ฑ์ด ๋ฐฉ์ง€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ localStorage๋‚˜ ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ api์— accessToken์„ ๋„ฃ์„๋•Œ ๊ทธ๋ฆฌ๊ณ  localStorage๋‚˜ ์ฟ ํ‚ค์— accessToken์„ ๋„ฃ์„ ๋•Œ ๊ฐ๊ฐ ๋ณตํ˜ธํ™” ์•”ํ˜ธํ™” ๊ณผ์ •์„ crpto ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ํ‚ค๊ฐ’์„ ๋„ฃ์„ํ…๋ฐ ์ด๋Š” react ๋•๋ถ„์— xss๋กœ ๊ณต๊ฐœ๋  ์œ„ํ—˜์ด ๊ฐ์†Œ๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ €๋Š” localStorage์— accessToken์„ ์ €์žฅํ•˜๋˜ crypto ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋„ฃ์„๋•Œ์™€ ๊บผ๋‚ผ๋•Œ ๊ฐ๊ฐ ์•”ํ˜ธํ™” ๋ณตํ˜ธํ™” ๊ณผ์ •์„ ๋„ฃ์Œ์œผ๋กœ์„œ ์™ธ๋ถ€๊ณต๊ฐœ๋ฐฉ์ง€๋ฅผ ํ•˜๋ฉฐ ์ธ์ฆ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์ด๋•Œ ์•”ํ˜ธํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋กœ์„œ cryto-js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.
AES ์•”ํ˜ธํ™” ๋ฐฉ๋ฒ•์œผ๋กœ ์–‘๋ฐฉํ–ฅ ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ๋ณด์•ˆ ์ €์žฅ ๋ฐ ๊บผ๋‚ด์˜ค๊ธฐ

avoidLocalStorageUndefined ํ•จ์ˆ˜๋Š” next๊ฐ€ ์ฒ˜์Œ ๋นŒ๋“œ ๋ ๋•Œ ์ปดํฌ๋„ŒํŠธ ๋กœ์ปฌ๋ณ€์ˆ˜์— ์ „์—ญ๊ฐ์ฒด ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋ฉด window ์ „์—ญ๊ฐ์ฒด๋ฅผ ์ฝ์ง€ ๋ชปํ•˜๋Š” ์—๋Ÿฌ๋•Œ๋ฌธ์— ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. static page๋กœ ๋กœ๋“œ ๋ ๋•Œ window ๊ฐ€ undefined ๋กœ ์ฝํžˆ๋Š” ์—๋Ÿฌ๋ฅผ ํ”ผํ•˜๊ณ ์ž ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ ๊ณผ์ •

์ฒ˜์Œ์— ๋กœ๊ทธ์ธ์„ ํ•˜๋ฉด login ํ•จ์ˆ˜ -> loginSuccess ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. loginSuccess์—์„œ ๋กœ๊ทธ์ธ ์„ฑ๊ณต์‹œ ๋ฐ›๋Š” ์œ ์ €๋ฐ์ดํ„ฐ์™€ ๋กœ๊ทธ์ธ ๋‹น์‹œ์˜ ์‹œ๊ฐ„์„ localStorage์— ๋ณด์•ˆ์ €์žฅ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  accessToken ์ธ์ฆ์ด ํ•„์š”ํ•œ ํ•จ์ˆ˜์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ง์ ‘ ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์—์„œ ๊ฐ’์„ ๋ฐ›์•„์™€ ๋ณตํ˜ธํ™” ํ•œ๊ฐ’์„ ๋„ฃ์–ด ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  401 ์—๋Ÿฌ ํ•ธ๋“ค๋ง์„ ํ†ตํ•ด accessToken์ด ์ธ์ฆ๋งŒ๋ฃŒ์‹œ ์žฌ ๋ฐœ๊ธ‰ ํ•จ์ˆ˜์ธ grantRefresh๋ฅผ ํ†ตํ•ด ์žฌ๋ฐœ๊ธ‰ ๋ฐ›์Šต๋‹ˆ๋‹ค.

  const getNewAlarms = async () => {
    const response = await axios
      .get("/users/alarm", {
        headers: {
          Authorization: getSecureLocalStorage("accessToken"),
        },
      })
      .catch((err) => {
        console.log(err, "์ƒˆ๋กœ์šด ๋ฉ”์„ธ์ง€ ๋ฐ›์•„์˜ค๊ธฐ ์‹คํŒจ");
        return err.response;
      });
    if (response.status === 401) {
      grantRefresh();
      return;
    }

accessToken์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„

accessToken์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„์€ 30๋ถ„ ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋กœ ์ด๋™ํ• ๋•Œ๋งˆ๋‹ค accessToken์„ ์žฌ๋ฐœ๊ธ‰ ๋ฐ›์„ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์‹œ loginTime์„ ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜๋Š”๋ฐ ๊ทธ์ด์œ ๋Š” ์ƒˆ๋กœ์šดํŽ˜์ด์ง€์— ๋“ค์–ด๊ฐ€๋ฉด ๋กœ๊ทธ์ธ ์‹œ๊ฐ„์œผ๋กœ๋ถ€ํ„ฐ ํ˜„์žฌ์‹œ๊ฐ„์ด 30๋ถ„ ์ด ๋‹ค๋˜์–ด๊ฐ€๋ฉด accessToken์„ ์žฌ๋ฐœ๊ธ‰ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ชจ๋“  ํŽ˜์ด์ง€์˜ ๊ฐ€์žฅ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— ์œ„ ์ฝ”๋“œ๋ฅผ ๋„ฃ์Œ์œผ๋กœ์„œ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€ ์ง„์ž…์‹œ๋งˆ๋‹ค ์žฌ์ธ์ฆ ๋‚จ์€ ์‹œ๊ฐ„์„ ๊ณ„์‚ฐํ•˜์—ฌ ์‹œ๊ฐ„์ด ์žฌ์ธ์ฆ ์‹œ๊ฐ„์ด ๋˜๋ฉด ์žฌ์ธ์ฆ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

profile
์ผ์ƒ์„ ๊ธฐ๋กํ•˜๋Š” ์‚ถ์„ ์‚ฌ๋Š” ๊ฐœ๋ฐœ์ž โœ’๏ธ #front_end ๐Ÿ’ป

0๊ฐœ์˜ ๋Œ“๊ธ€