๐Ÿ”‘ ์ธ์ฆ, ๊ณ ๋ฅผ ๊ฒŒ ๋งŽ๋‹ค

์ธ์ฆ ์ˆ˜๋‹จ, ์ „๋‹ฌ ๋ฐฉ์‹, ์ €์žฅ์†Œ โ€” ๋กœ๊ทธ์ธ ํ•˜๋‚˜์— ๊ฒฐ์ •ํ•  ๊ฒƒ
2026๋…„ 4์›” 6์ผ

๐Ÿ”‘ ์ธ์ฆ, ๊ณ ๋ฅผ ๊ฒŒ ๋งŽ๋‹ค

๋ฐฑ์—”๋“œ ์Šคํ„ฐ๋””๋ฅผ ํ•˜๋ฉด์„œ ๋“œ๋””์–ด ์ธ์ฆ์„ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ฐ•์˜์—์„œ๋Š” ๊ฐ€๋ณ๊ฒŒ JWT ํ† ํฐ์„ ํ—ค๋”์— ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹๋งŒ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์–ด ๊ฐ€๋ณ๊ฒŒ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๋“ค์— ๋Œ€ํ•ด ๋” ๊ณต๋ถ€ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.


์ธ์ฆ์—๋Š” ๋„ค ๊ฐ€์ง€ ์„ ํƒ์ง€๊ฐ€ ์žˆ๋‹ค

์ธ์ฆ์„ ๊ณต๋ถ€ํ•˜๋‹ค ๋ณด๋ฉด "JWT vs ์„ธ์…˜", "์ฟ ํ‚ค vs ํ—ค๋”" ๊ฐ™์€ ๋น„๊ต๋ฅผ ์ž์ฃผ ๋งˆ์ฃผ์นœ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ด๊ฒƒ๋“ค์€ ์„œ๋กœ ๋‹ค๋ฅธ ์ธต์œ„์˜ ์ด์•ผ๊ธฐ๋‹ค.

์„ ํƒ์ง€์งˆ๋ฌธ์˜ˆ์‹œ
์ธ์ฆ ์ˆ˜๋‹จ๋ญ˜๋กœ ์‹ ์›์„ ์ฆ๋ช…ํ•˜๋‚˜?์„ธ์…˜ID, JWT
์ „๋‹ฌ ๋ฐฉ์‹ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์–ด๋–ค ๊ฒฝ๋กœ๋กœ ์ฃผ๊ณ ๋ฐ›๋‚˜?์ฟ ํ‚ค, ํ—ค๋”
์„œ๋ฒ„ ์ €์žฅ์†Œ์„œ๋ฒ„๋Š” ์–ด๋””์— ๊ธฐ์–ตํ•ด๋‘๋‚˜?์—†์Œ, Redis, DB
ํด๋ผ์ด์–ธํŠธ ์ €์žฅ์†Œํด๋ผ์ด์–ธํŠธ๋Š” ์–ด๋””์— ๋ณด๊ด€ํ•˜๋‚˜?์ฟ ํ‚ค, ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€, Secure Store

์ด ๋„ค ์„ ํƒ์ง€๋Š” ๋…๋ฆฝ์ ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์กฐํ•ฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ™์€ JWT๋ผ๋„, ์›น์—์„œ๋Š” ์ฟ ํ‚ค์— ๋‹ด์•„ ๋ณด๋‚ด๊ณ  ๋ชจ๋ฐ”์ผ์—์„œ๋Š” ํ—ค๋”์— ๋ถ™์—ฌ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ์ธ์ฆ ์ˆ˜๋‹จ์ด ๊ฐ™์•„๋„ ์ „๋‹ฌ ๋ฐฉ์‹์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.


์ธ์ฆ ์ˆ˜๋‹จ โ€” "๋ญ˜๋กœ ์ฆ๋ช…ํ•˜๋‚˜?"

์ธ์ฆ์ด๋ž€ ์„œ๋ฒ„์—๊ฒŒ "๋‚˜ ์ด ์‚ฌ๋žŒ์ด์•ผ"๋ฅผ ์ฆ๋ช…ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์„ธ์…˜ (Session)

์„œ๋ฒ„๊ฐ€ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค. ์„ธ์…˜ID๋Š” ์—ด์‡ ์ผ ๋ฟ์ด๊ณ , ์‹ค์ œ ์ •๋ณด๋Š” ์„œ๋ฒ„ ์ €์žฅ์†Œ์— ์žˆ๋‹ค.

JWT (JSON Web Token)

์„ธ์…˜๊ณผ ๋ฐ˜๋Œ€๋กœ ์„œ๋ฒ„๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ๊ธฐ์–ตํ•˜์ง€ ์•Š๋Š”๋‹ค(Stateless)

ํ† ํฐ ์ž์ฒด์— ์œ ์ € ์ •๋ณด(ID, ์—ญํ•  ๋“ฑ)๊ฐ€ ๋“ค์–ด์žˆ๊ณ , ์„œ๋ฒ„๋Š” "์ด ํ† ํฐ์ด ๋‚ด๊ฐ€ ์„œ๋ช…ํ•œ ๊ฒŒ ๋งž๋Š”์ง€"๋งŒ ํ™•์ธํ•œ๋‹ค.

์—ฌ๊ธฐ์— ํ•จ์ •์ด ์žˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ๊ธฐ์–ตํ•˜์ง€ ์•Š์œผ๋‹ˆ, ํ† ํฐ์„ ์„œ๋ฒ„์—์„œ ๋ฌดํšจํ™”ํ•  ์ˆ˜ ์—†๋‹ค. ์œ ์ €๊ฐ€ ๋กœ๊ทธ์•„์›ƒํ•ด๋„, ํ† ํฐ์ด ํƒˆ์ทจ๋ผ๋„, ๋งŒ๋ฃŒ ์‹œ๊ฐ„์ด ๋  ๋•Œ๊นŒ์ง€ ํ† ํฐ์€ ์œ ํšจํ•˜๋‹ค.

JWT + Refresh Token

์ˆœ์ˆ˜ JWT์˜ ํ•œ๊ณ„๋ฅผ ๋ณด์™„ํ•œ ๋ฐฉ์‹์ด๋‹ค.

Access Token ์ˆ˜๋ช…์„ ์งง๊ฒŒ ๊ฐ€์ ธ๊ฐ€ ํƒˆ์ทจ ์œ„ํ—˜์„ ์ค„์ด๊ณ , Refresh Token์€ ์„œ๋ฒ„๊ฐ€ ๊ด€๋ฆฌํ•ด ๊ฐ•์ œ ๋ฌดํšจํ™”๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค. Stateless์˜ ์žฅ์ ์€ ์‚ด๋ฆฌ๋˜, ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์„œ๋ฒ„๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๋ฐฉ์‹์ด๋‹ค.

๋น„๊ต

์„ธ์…˜JWTJWT + Refresh
์„œ๋ฒ„ ์ƒํƒœStatefulStatelessํ•˜์ด๋ธŒ๋ฆฌ๋“œ
๊ฐ•์ œ ๋กœ๊ทธ์•„์›ƒ์‰ฌ์›€์–ด๋ ค์›€๊ฐ€๋Šฅ
์„œ๋ฒ„ ๋ถ€๋‹ด๋งค ์š”์ฒญ ์ €์žฅ์†Œ ์กฐํšŒ์„œ๋ช… ๊ฒ€์ฆ๋งŒ์„œ๋ช… ๊ฒ€์ฆ + ์ผ๋ถ€ ์กฐํšŒ
ํ† ํฐ ํƒˆ์ทจ ์‹œ์„ธ์…˜ ์‚ญ์ œ๋กœ ์ฐจ๋‹จ๋งŒ๋ฃŒ๊นŒ์ง€ ์œ ํšจ์งง์€ ์ˆ˜๋ช…์œผ๋กœ ์™„ํ™”

์ „๋‹ฌ ๋ฐฉ์‹ โ€” "์–ด๋–ป๊ฒŒ ๋ณด๋‚ด๋‚˜?"

์ธ์ฆ ์ˆ˜๋‹จ์„ ์ •ํ–ˆ์œผ๋ฉด, ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์–ด๋–ค ๊ฒฝ๋กœ๋กœ ์ฃผ๊ณ ๋ฐ›์„์ง€ ์ •ํ•ด์•ผ ํ•œ๋‹ค.

์„œ๋ฒ„๊ฐ€ ์‘๋‹ต์— Set-Cookie๋ฅผ ๋ณด๋‚ด๋ฉด, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ดํ›„ ๋งค ์š”์ฒญ์— ์ฟ ํ‚ค๋ฅผ ์ž๋™์œผ๋กœ ํฌํ•จ์‹œํ‚จ๋‹ค. ํ”„๋ก ํŠธ ์ฝ”๋“œ์—์„œ ๋ณ„๋„๋กœ ๋ถ™์ด๋Š” ์ž‘์—…์ด ํ•„์š” ์—†๋‹ค.

๊ฐ€์žฅ ํฐ ์žฅ์ ์€ HttpOnly ์˜ต์…˜์ด๋‹ค. JavaScript์—์„œ ์ฟ ํ‚ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์–ด, ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ† ํฐ์„ ํ›”์น˜๋Š” XSS ๊ณต๊ฒฉ์„ ์›์ฒœ ์ฐจ๋‹จํ•œ๋‹ค.

Secure๊ณผ SameSite์˜ต์…˜์œผ๋กœ๋„ ์ค‘๊ฐ„์ž ๊ณต๊ฒฉ์ด๋‚˜ csrf๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ ์€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ชจ๋ฐ”์ผ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์—๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์—†์œผ๋‹ˆ ์ž๋™ ์ „์†ก์ด๋‚˜ HttpOnly ๋ณดํ˜ธ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.

Authorization ํ—ค๋” (Bearer Token)

์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์ฝ”๋“œ๋กœ ์ง์ ‘ ํ—ค๋”์— ํ† ํฐ์„ ๋ถ™์ธ๋‹ค.

๋ธŒ๋ผ์šฐ์ € ์˜์กด์ด ์—†์–ด์„œ ๋ชจ๋ฐ”์ผ ์•ฑ, SPA, ์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹  ์–ด๋””์„œ๋“  ์“ธ ์ˆ˜ ์žˆ๋‹ค. ๋Œ€์‹  ํ† ํฐ์„ ์ €์žฅํ•˜๊ณ  ๊บผ๋‚ด์„œ ๋ถ™์ด๋Š” ๊ฑด ๊ฐœ๋ฐœ์ž ๋ชซ์ด๋‹ค. ํ”„๋ก ํŠธ ์ž…์žฅ์—์„œ ํ† ํฐ ๊ด€๋ฆฌ ๋ฐฉ์‹์ด ์ค‘์š”ํ•ด์ง€๋Š” ์ด์œ ๋‹ค.

๋น„๊ต

์ฟ ํ‚คAuthorization ํ—ค๋”
์ „์†ก๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ž๋™์ฝ”๋“œ๋กœ ์ง์ ‘
XSS ๋ฐฉ์–ดHttpOnly๋กœ JS ์ ‘๊ทผ ์ฐจ๋‹จ์ €์žฅ์†Œ์— ๋”ฐ๋ผ ๋‹ค๋ฆ„
CSRF ์œ„ํ—˜์žˆ์Œ (SameSite๋กœ ์™„ํ™”)์—†์Œ
๋ชจ๋ฐ”์ผ๋ถˆํŽธํ•จ์ ํ•ฉ
์›น์ ํ•ฉ๊ฐ€๋Šฅ

์„œ๋ฒ„ ์ €์žฅ์†Œ โ€” "์„œ๋ฒ„๋Š” ์–ด๋””์— ๊ธฐ์–ตํ•˜๋‚˜?"

์ˆœ์ˆ˜ JWT์ฒ˜๋Ÿผ ์„œ๋ฒ„๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋น„์Šค์—์„œ๋Š” ์„œ๋ฒ„ ์ชฝ์—๋„ ๋ญ”๊ฐ€๋ฅผ ์ €์žฅํ•œ๋‹ค. ์„ธ์…˜ ์ •๋ณด์ผ ์ˆ˜๋„ ์žˆ๊ณ , ํ† ํฐ ์œ ํšจ ์—ฌ๋ถ€์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

์—†์Œ (์ˆœ์ˆ˜ Stateless)

์„œ๋ฒ„๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. JWT ์„œ๋ช…๋งŒ ๊ฒ€์ฆํ•˜๋ฉด ๋์ด๋‹ค.

์„œ๋ฒ„ ํ™•์žฅ์ด ์‰ฝ๋‹ค. ์„œ๋ฒ„๊ฐ€ 10๋Œ€๋“  100๋Œ€๋“  ๊ฐ™์€ ๋น„๋ฐ€ํ‚ค๋งŒ ๊ณต์œ ํ•˜๋ฉด ์–ด๋А ์„œ๋ฒ„์—์„œ๋“  ํ† ํฐ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค. ๋Œ€์‹  ๊ฐ•์ œ ๋ฌดํšจํ™”๊ฐ€ ์•ˆ ๋œ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ (์„œ๋ฒ„ ๋ณ€์ˆ˜)

์„œ๋ฒ„ ํ”„๋กœ์„ธ์Šค ๋ฉ”๋ชจ๋ฆฌ์— ์„ธ์…˜์„ ์ €์žฅํ•œ๋‹ค. ๊ฐ€์žฅ ๋น ๋ฅด์ง€๋งŒ, ์„œ๋ฒ„๊ฐ€ ์—ฌ๋Ÿฌ ๋Œ€๋ฉด ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค. ์œ ์ €๊ฐ€ A ์„œ๋ฒ„์—์„œ ๋กœ๊ทธ์ธํ–ˆ๋Š”๋ฐ ๋‹ค์Œ ์š”์ฒญ์ด B ์„œ๋ฒ„๋กœ ๊ฐ€๋ฉด ์„ธ์…˜์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค.

Redis

์ธ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ์†Œ๋กœ, DB๋ณด๋‹ค ๋น ๋ฅด๊ณ  ์„œ๋ฒ„ ๊ฐ„ ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

์„œ๋ฒ„๊ฐ€ ์—ฌ๋Ÿฌ ๋Œ€์—ฌ๋„ ๋ชจ๋‘ ๊ฐ™์€ Redis๋ฅผ ๋ฐ”๋ผ๋ณด๋‹ˆ ์„ธ์…˜ ๊ณต์œ  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ๋‹ค. ํ™œ์šฉ ์˜ˆ์‹œ๋„ ๋‹ค์–‘ํ•˜๋‹ค.

์šฉ๋„์ €์žฅํ•˜๋Š” ๊ฒƒ์˜ˆ์‹œ
์„ธ์…˜ ์ €์žฅ์†Œ์„ธ์…˜ID โ†’ ์œ ์ € ์ •๋ณด์ „ํ†ต ์„ธ์…˜ ๋ฐฉ์‹
ํ† ํฐ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ๋กœ๊ทธ์•„์›ƒ๋œ ํ† ํฐ ID(jti)JWT ๊ฐ•์ œ ๋ฌดํšจํ™”
์„ธ์…˜ ์œ ํšจ์„ฑ์„ธ์…˜ID โ†’ ์œ ํšจ ์—ฌ๋ถ€ (Y/N)JWT + ์„ธ์…˜ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ
Refresh TokenRefresh Token ํ•ด์‹œํ† ํฐ ๊ฐฑ์‹  ๊ด€๋ฆฌ

DB (PostgreSQL, MySQL ๋“ฑ)

์˜๊ตฌ ์ €์žฅ์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. Redis๋ณด๋‹ค ๋А๋ฆฌ์ง€๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ ์•„๊ฐ€์ง€ ์•Š๋Š”๋‹ค. ์‹ค์‹œ๊ฐ„ ์กฐํšŒ๋Š” Redis์—, ๋ณด์•ˆ ๋กœ๊ทธ๋‚˜ ์„ธ์…˜ ์ด๋ ฅ์€ DB์— ๋‘๋Š” ์‹์œผ๋กœ ํ•จ๊ป˜ ์“ฐ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

๋น„๊ต

์—†์Œ๋ฉ”๋ชจ๋ฆฌRedisDB
์†๋„โ€”๊ฐ€์žฅ ๋น ๋ฆ„๋น ๋ฆ„์ƒ๋Œ€์ ์œผ๋กœ ๋А๋ฆผ
์„œ๋ฒ„ ํ™•์žฅ์ž์œ ๋กœ์›€๋ถˆ๊ฐ€๊ฐ€๋Šฅ๊ฐ€๋Šฅ
์˜๊ตฌ์„ฑโ€”์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ ์†Œ๋ฉธ์„ค์ •์— ๋”ฐ๋ผ์˜๊ตฌ
๊ฐ•์ œ ๋ฌดํšจํ™”๋ถˆ๊ฐ€๊ฐ€๋Šฅ๊ฐ€๋Šฅ๊ฐ€๋Šฅ
์ฃผ ์šฉ๋„์ˆœ์ˆ˜ JWT๋‹จ์ผ ์„œ๋ฒ„ ๊ฐœ๋ฐœ์„ธ์…˜/ํ† ํฐ ๊ด€๋ฆฌ์ด๋ ฅ/์˜๊ตฌ ์ €์žฅ

ํด๋ผ์ด์–ธํŠธ ์ €์žฅ์†Œ โ€” "ํด๋ผ์ด์–ธํŠธ๋Š” ์–ด๋””์— ๋ณด๊ด€ํ•˜๋‚˜?"

์„œ๋ฒ„์—์„œ ๋ฐ›์€ ํ† ํฐ์ด๋‚˜ ์„ธ์…˜ID๋ฅผ ํด๋ผ์ด์–ธํŠธ ์–ด๋””์— ์ €์žฅํ• ์ง€์˜ ๋ฌธ์ œ๋‹ค. ์ด ์„ ํƒ์ด ๋ณด์•ˆ์— ์ง์ ‘์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค.

์ฟ ํ‚ค

์„œ๋ฒ„๊ฐ€ Set-Cookie๋กœ ์„ค์ •ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ด€๋ฆฌํ•œ๋‹ค. HttpOnly๋ฅผ ์ผœ๋ฉด JavaScript์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€ (localStorage)

๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋‹ซ์•„๋„ ์œ ์ง€๋œ๋‹ค. ํŽธํ•˜์ง€๋งŒ JavaScript๋กœ ์ž์œ ๋กญ๊ฒŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด, XSS ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•˜๋‹ค.

์„ธ์…˜์Šคํ† ๋ฆฌ์ง€ (sessionStorage)

๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์™€ ๋น„์Šทํ•˜์ง€๋งŒ ํƒญ์„ ๋‹ซ์œผ๋ฉด ์‚ฌ๋ผ์ง„๋‹ค. XSS ์ทจ์•ฝ์ ์€ ๋™์ผํ•˜๋‹ค.

Secure Store (๋ชจ๋ฐ”์ผ)

๋ชจ๋ฐ”์ผ OS๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์•”ํ˜ธํ™”๋œ ์ €์žฅ์†Œ๋‹ค. iOS์˜ Keychain, Android์˜ Keystore๊ฐ€ ์ด์— ํ•ด๋‹นํ•œ๋‹ค. React Native์—์„œ๋Š” expo-secure-store ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•œ๋‹ค. ์•ฑ ์™ธ๋ถ€์—์„œ๋Š” ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ฉ”๋ชจ๋ฆฌ (๋ณ€์ˆ˜)

์ƒˆ๋กœ๊ณ ์นจํ•˜๋ฉด ์‚ฌ๋ผ์ง„๋‹ค. ๊ฐ€์žฅ ์•ˆ์ „ํ•˜์ง€๋งŒ ๊ฐ€์žฅ ๋ถˆํŽธํ•˜๋‹ค. ์ˆ˜๋ช…์ด ์งง๊ณ  Refresh Token์œผ๋กœ ์žฌ๋ฐœ๊ธ‰ ๊ฐ€๋Šฅํ•œ Access Token์— ์“ฐ๊ธฐ๋„ ํ•œ๋‹ค.

๋น„๊ต

์ฟ ํ‚ค (HttpOnly)๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์„ธ์…˜์Šคํ† ๋ฆฌ์ง€Secure Store๋ฉ”๋ชจ๋ฆฌ
JS ์ ‘๊ทผ๋ถˆ๊ฐ€๊ฐ€๋Šฅ๊ฐ€๋Šฅ๋ถˆ๊ฐ€ (์•ฑ ์™ธ๋ถ€)๊ฐ€๋Šฅ (์•ฑ ๋‚ด๋ถ€๋งŒ)
XSS ์œ„ํ—˜์•ˆ์ „์ทจ์•ฝ์ทจ์•ฝํ•ด๋‹น ์—†์Œ์•ˆ์ „
์ง€์†์„ฑ๋งŒ๋ฃŒ๊นŒ์ง€์˜๊ตฌํƒญ ๋‹ซ์œผ๋ฉด ์†Œ๋ฉธ์˜๊ตฌ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ์†Œ๋ฉธ
ํ™˜๊ฒฝ์›น์›น์›น๋ชจ๋ฐ”์ผ์–ด๋””๋“ 

๋ณด์•ˆ ์œ„ํ˜‘์ด ์„ ํƒ์„ ๊ฒฐ์ •ํ•œ๋‹ค

ํ™˜๊ฒฝ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ €์žฅ์†Œ๋ฅผ ์“ฐ๋Š” ์ด์œ ๋Š” ์œ„ํ˜‘์˜ ์ข…๋ฅ˜๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์›น์˜ ์ฃผ์š” ์œ„ํ˜‘์€ XSS๋‹ค. ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํŽ˜์ด์ง€์— ์‚ฝ์ž…๋˜๋ฉด JavaScript๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ €์žฅ์†Œ์˜ ํ† ํฐ์„ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ๋‹ค. JS๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” HttpOnly ์ฟ ํ‚ค๊ฐ€ ์•ˆ์ „ํ•œ ์ด์œ ๋‹ค.

๋ชจ๋ฐ”์ผ์˜ ์ฃผ์š” ์œ„ํ˜‘์€ ๊ธฐ๊ธฐ ํƒˆ์ทจ์™€ ๋ฆฌ๋ฒ„์Šค ์—”์ง€๋‹ˆ์–ด๋ง์ด๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์—†์œผ๋‹ˆ XSS๋Š” ํ•ด๋‹น์ด ์—†๊ณ , OS ๋ ˆ๋ฒจ์—์„œ ์•”ํ˜ธํ™”ํ•ด์ฃผ๋Š” Secure Store๊ฐ€ ๊ฐ€์žฅ ์•ˆ์ „ํ•˜๋‹ค. HttpOnly๊ฐ€ JS ์ ‘๊ทผ์„ ๋ง‰๋Š” ๋ณดํ˜ธ๋ผ๋ฉด, Secure Store๋Š” ์•ฑ ์™ธ๋ถ€์˜ ์ ‘๊ทผ์„ ๋ง‰๋Š” ๋ณดํ˜ธ์ธ ์…ˆ์ด๋‹ค.

ํ™˜๊ฒฝ์ฃผ์š” ์œ„ํ˜‘์ถ”์ฒœ ์ €์žฅ์†Œ์ถ”์ฒœ ์ „๋‹ฌ ๋ฐฉ์‹
์›นXSSHttpOnly ์ฟ ํ‚ค์ฟ ํ‚ค (์ž๋™ ์ „์†ก)
๋ชจ๋ฐ”์ผ ์•ฑ๊ธฐ๊ธฐ ํƒˆ์ทจSecure Storeํ—ค๋” (์ง์ ‘ ์ „์†ก)
์›น + ๋ชจ๋ฐ”์ผ๋‘˜ ๋‹คํ™˜๊ฒฝ๋ณ„ ๋ถ„๊ธฐ์ฟ ํ‚ค + ํ—ค๋” ๋‘˜ ๋‹ค ์ง€์›

๋งˆ์น˜๋ฉฐ

๊ทธ๋™์•ˆ ์„œ๋ฒ„๊ฐ€ ์ด ํ† ํฐ์„ ์–ด๋–ป๊ฒŒ ๊ฒ€์ฆํ•˜๋Š”์ง€, ์„ธ์…˜์„ ์–ด๋””์— ์ €์žฅํ•˜๋Š”์ง€, ์™œ Redis๋ฅผ ์“ฐ๋Š”์ง€ ๊ฐ™์€ ๊ฑด ์ƒ๊ฐํ•ด๋ณธ ์ ์ด ์—†์—ˆ๋‹ค.

๋ฐฑ์—”๋“œ ์Šคํ„ฐ๋””๋ฅผ ํ•˜๋ฉด์„œ ์„œ๋ฒ„๋Š” ๋‹จ์ˆœํžˆ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜๊ณ  ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์—์„œ ๋์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ , ๊ธ€์„ ์“ด ๊ฒƒ ์ด์™ธ์—๋„ ์ด๋ฏธ ํ๊ธฐ๋œ Refresh Token์ด ์žฌ์‚ฌ์šฉ๋˜๋ฉด ํƒˆ์ทจ๋กœ ํŒ๋‹จํ•ด ์ „์ฒด ์„ธ์…˜์„ ๊ฐ•์ œ ๋กœ๊ทธ์•„์›ƒ์‹œํ‚ค๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ์ง€(Reuse Detection), ์„ธ์…˜ ์œ ํšจ์„ฑ์„ Redis์—์„œ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•˜๋Š” ์บ์‹ฑ ์ „๋žต ๋“ฑ ๋ณด์•ˆ์„ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ํ† ํฐ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹๋“ฑ ๋‹ค์–‘ํ•œ ๊ฒƒ์„ ๊ณต๋ถ€ํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค !...