๐Ÿฅฝ[JWT] - ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ

dev_itzel_02โœจยท2025๋…„ 4์›” 10์ผ

๐ŸฅฝDeep-Dive

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

[์ •์˜]

JSON Web Token

์ธ์ฆ์— ํ•„์š”ํ•œ ์ •๋ณด๋“ค์„ ์•”ํ˜ธํ™”์‹œํ‚จ JSON ํ† ํฐ

JWT ํ† ํฐ์„ HTTP ํ—ค๋”์— ์‹ค์–ด ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐฉ์‹

(JWT ํ† ํฐ = Access Token)

[๊ตฌ์กฐ]

. ์„ ๊ตฌ๋ถ„์ž๋กœ Header, Payload, Signature ๋กœ ๋‚˜๋‰œ๋‹ค.

  • Header : JWT์—์„œ ์‚ฌ์šฉํ•  ํƒ€์ž…๊ณผ ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ข…๋ฅ˜
  • Payload : ์„œ๋ฒ„์—์„œ ์ฒจ๋ถ€ํ•œ ์‚ฌ์šฉ์ž ๊ถŒํ•œ ์ •๋ณด์™€ ๋ฐ์ดํ„ฐ โ†’ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋  ์ •๋ณด๋“ค
    • key-value ๋กœ ์ด๋ฃจ์–ด์ง„ ํ•œ ์Œ์„ Claim ์ด๋ผ๊ณ  ํ•œ๋‹ค.
    • ๋“ฑ๋ก๋œ ํด๋ ˆ์ž„
      • iss(issuer; ๋ฐœํ–‰์ž)
      • exp(expireation time; ๋งŒ๋ฃŒ ์‹œ๊ฐ„)
      • sub(subject; ์ œ๋ชฉ)
      • iat(issued At; ๋ฐœํ–‰ ์‹œ๊ฐ„)
      • jti(JWI ID)
    • ๊ณต๊ฐœ ํด๋ ˆ์ž„
      • ๊ณต๊ฐœ์šฉ ์ •๋ณด ์ „๋‹ฌ์„ ์œ„ํ•จ
      • ํด๋ ˆ์ž„ ์ด๋ฆ„์„ ์ฃผ๋กœ URI๋กœ ์ง€์Œ
    • ๋น„๊ณต๊ฐœ ํด๋ ˆ์ž„
      • ๊ณต๊ฐœ๋˜๋ฉด ์•ˆ ๋˜๋Š” ํด๋ ˆ์ž„
      • ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹ ์— ์‚ฌ์šฉ
  • Signature : Header & Payload ๋ฅผ ์ธ์ฝ”๋”ฉํ•œ ํ›„ Header์— ๋ช…์‹œ๋œ ํ•ด์‹œํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜๊ณ , ๋น„๋ฐ€ํ‚ค๋กœ ํ•ด์‹œ๊ฐ’ ์ƒ์„ฑ


-> ํ† ํฐ์˜ ์œ„๋ณ€์กฐ ์—ฌ๋ถ€ ํ™•์ธ์— ์‚ฌ์šฉ

[์ธ์ฆ ๊ณผ์ •]


1. ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋ฒ„์— ๋กœ๊ทธ์ธ ์ธ์ฆ ์š”์ฒญ
2. ์„œ๋ฒ„์—์„œ Header, Payload, Signature ์ •์˜ ํ›„ JWT(์•ก์„ธ์Šค + ๋ฆฌํ”„๋ ˆ์‹œ)๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ฟ ํ‚ค์— ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก

  • ์„œ๋ฒ„๋Š” ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ DB์— ๋ณ„๋„ ์ €์žฅ

3.ํด๋ผ์ด์–ธํŠธ๋Š” JWT๋ฅผ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ

  • ์„œ๋ฒ„์— API ์š”์ฒญ ์‹œ Authorization header ์— Access Token์„ ๋‹ด์•„ ์ „์†ก

4.์„œ๋ฒ„๋Š” ํ† ํฐ์˜ ์•ก์„ธ์Šค ํ† ํฐ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

  • ์œ ํšจ X โ†’ ํ† ํฐ ๋งŒ๋ฃŒ ์—๋Ÿฌ ๋ฐ˜ํ™˜
    • ํด๋ผ์ด์–ธํŠธ๋Š” ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์œผ๋กœ ์ƒˆ๋กœ์šด ์•ก์„ธ์Šค ํ† ํฐ ๋ฐœ๊ธ‰ ์š”์ฒญ
    • ์„œ๋ฒ„๋Š” DB์˜ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ๊ณผ ๋น„๊ต ํ›„ ์œ ํšจํ•˜๋‹ค๋ฉด ์ƒˆ๋กœ์šด ์•ก์„ธ์Šค ํ† ํฐ ๋ฐœ๊ธ‰
  • ์œ ํšจ O โ†’ ์š”์ฒญ ์ฒ˜๋ฆฌ

[๊ถ๊ธˆ์ฆ]

๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ํƒˆ์ทจ๋‹นํ•œ๋‹ค๋ฉด ๋ฌด์šฉ์ง€๋ฌผ ์•„๋‹๊นŒ ?

YES !

ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” โ€œ๋ฌด์ƒํƒœ์„ฑโ€ ์ด๋‹ค.

์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ํ† ํฐ์ด ์„œ๋ฒ„๊ฐ€ ์•„๋‹Œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ฒ„์—์„œ ๋”ฐ๋กœ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ฆ‰, stateless ์ธ ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์•ก์„ธ์Šค ํ† ํฐ์„ ํƒˆ์ทจ๋‹นํ•˜๋ฉด ์„œ๋ฒ„๋Š” ํ™•์ธํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด๋ผ๋Š” ๊ฐœ๋…์ด ์ƒ๊ฒผ๋‹ค.

์•ก์„ธ์Šค ํ† ํฐ์˜ ์œ ํšจ๊ธฐ๊ฐ„(๋ณดํ†ต 30๋ถ„)์„ ์งง๊ฒŒ ํ•œ๋‹ค๋ฉด ํƒˆ์ทจ๋‹นํ•˜๋”๋ผ๋„ ์˜ค๋ž˜ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•  ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์‚ฌ์šฉ์žฅ ์ž…์žฅ์—์„œ๋Š” ์œ ํšจ๊ธฐ๊ฐ„์ด ๋๋‚  ๋•Œ๋งˆ๋‹ค ํ† ํฐ์„ ์žฌ๋ฐœ๊ธ‰ํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ๊ธธ๊ฒŒ ํ•˜์—ฌ(๋ณดํ†ต 2์ฃผ) ์•ก์„ธ์Šค ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜๋ฉด ์ƒˆ๋กœ์šด ์•ก์„ธ์Šค ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ๋Š” ํด๋ผ์ด์–ธํŠธ ์ž…์žฅ์—์„œ๋Š” ๋กœ๊ทธ์ธ ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋А๊ปด์ง„๋‹ค.

ํ•˜์ง€๋งŒ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์€ โ€œ๋ฌดํšจํ™”โ€ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค. ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์€ ์„œ๋ฒ„์—์„œ๋„ ์ €์žฅ์„ ํ•˜๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ํƒˆ์ทจ๋‹นํ–ˆ์„ ๋•Œ, ํƒˆ์ทจ๋‹นํ–ˆ๋‹ค๋Š” ์–ด๋– ํ•œ ์š”์ฒญ์ด ์˜ค๋ฉด ํ† ํฐ์„ ๋ฌดํšจํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

โ‡’ Refresh Token์ด ํƒˆ์ทจ๋˜๋”๋ผ๋„ ์„œ๋ฒ„์˜ ๊ฒ€์ฆ์œผ๋กœ AccessToken ์žฌ๋ฐœ๊ธ‰์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ† ํฐ์€ ์–ด๋””์— ์ €์žฅ๋ ๊นŒ ?

Access Token์€ ์š”์ฒญ header์˜ authorization์— ๋‹ด๊ธด๋‹ค. โ†’ ๊ณต์‹ ๊ทœ๊ฒฉ

Refresh Token์€ http only cookie๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด js๋ฅผ ํ†ตํ•œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด์ง€๋ฏ€๋กœ ์Šคํฌ๋ฆฝํŠธ ์‚ฝ์ž… ๊ณต๊ฒฉ(XSS)์€ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ http secure โ†’ https๋กœ๋งŒ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ์ฟ ํ‚ค์— ๋ณด๊ด€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํƒˆ์ทจ ๊ฐ€๋Šฅ์„ฑ์€ ๊ฑฐ์˜ ์—†๋‹ค๊ณ  ํ•œ๋‹ค.

ํ† ํฐ์˜ ์œ ํšจ์„ฑ์€ ์–ด๋–ป๊ฒŒ ๊ฒ€์ฆํ• ๊นŒ ?

ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์—์„œ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์—†์ด ๋ฌด์ƒํƒœ๋กœ ์šด์˜ํ•œ๋‹ค๋ฉด, ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ํ† ํฐ์„ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ฒ€์ฆ์„ ํ•˜๋Š”๊ฑด์ง€ ๊ถ๊ธˆํ–ˆ๋‹ค.

  1. ์„œ๋ช… ๊ฒ€์ฆ
    1. ์„œ๋ฒ„๋Š” ํ† ํฐ์˜ Signature๋ฅผ ์„œ๋ฒ„์—๋งŒ ์žˆ๋Š” ๋น„๋ฐ€ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒ€์ฆ โ†’ ํ† ํฐ์˜ ์œ„๋ณ€์กฐ ํ™•์ธ ๊ฐ€๋Šฅ
  2. Payload์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„ ํ™•์ธ
    1. ํ† ํฐ์˜ exp ๋ฅผ ํ™•์ธํ•˜์—ฌ ์œ ํšจ ๊ธฐ๊ฐ„์ด ์ง€๋‚ฌ๋Š”์ง€ ํŒ๋‹จ

โ‡’ ์ฆ‰, ํ† ํฐ ๊ทธ ์ž์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ† ํฐ ์ž์ฒด๋กœ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•จ

[์ถ”๊ฐ€ ๋ณด์•ˆ ๊ฐ•ํ™” ๋ฐฉ๋ฒ•]

  1. JWT ํ† ํฐ์— JTI (JWT ID) ํฌํ•จ : ํ† ํฐ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ์ถ”๊ฐ€ํ•ด ์žฌ์‚ฌ์šฉ ๋ฐฉ์ง€
  2. ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ๊ด€๋ฆฌ : Access Token์€ ์งง๊ฒŒ, Refresh Token์€ ๊ธธ๊ฒŒ
  3. 2FA(Two-Factor Authentication) : ์ถ”๊ฐ€ ์ธ์ฆ ๋‹จ๊ณ„ ๋„์ž…

[์ถœ์ฒ˜]

profile
๐Ÿœ๐Ÿ‘ฃsteadiness๐Ÿœ๐Ÿ‘ฃ

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