๐Ÿ”’ JWT๋ž€?

์ตœ์Šนํ˜ยท2025๋…„ 8์›” 23์ผ
post-thumbnail

์›น ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๋‹ค ๋ณด๋ฉด ๊ฐ€์žฅ ๋จผ์ € ๋ถ€๋”ชํžˆ๋Š” ๊ฒƒ์ด โ€œ์‚ฌ์šฉ์ž ์ธ์ฆโ€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
์„ธ์…˜/์ฟ ํ‚ค ๋ฐฉ์‹๋ถ€ํ„ฐ OAuth, ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ๊นŒ์ง€ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•˜๋Š”๋ฐ, ๊ทธ์ค‘ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ด๋Š” ๊ฒƒ์ด JWT(Json Web Token) ์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” JWT๊ฐ€ ๋ฌด์—‡์ด๊ณ , ์™œ ํ•„์š”ํ•œ์ง€, ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ“ŒJWT(Json Web Toekn) ์ •์˜

JWT(Json Web Token) ๋Š” ์›น ํ‘œ์ค€(RFC 7519)์œผ๋กœ ์ •์˜๋œ ์ธ์ฆ ๋ฐ ์ •๋ณด ๊ตํ™˜์„ ์œ„ํ•œ ํ† ํฐ ํ˜•์‹์ž…๋‹ˆ๋‹ค.

  • JSON ํฌ๋งท์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์Šต๋‹ˆ๋‹ค.

  • ์ „์ž์„œ๋ช…(Signature) ์„ ํฌํ•จํ•ด ์œ„ยท๋ณ€์กฐ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜์„ ์ง์ ‘ ์ €์žฅํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ Stateless ์ธ์ฆ ๋ฐฉ์‹์— ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ฆ‰, ํด๋ผ์ด์–ธํŠธ๊ฐ€ JWT๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ์„œ๋ฒ„๋Š” ์ถ”๊ฐ€ DB ์กฐํšŒ๋‚˜ ์„ธ์…˜ ์ €์žฅ์†Œ ์—†์ด๋„ ์‚ฌ์šฉ์ž์˜ ์‹ ์›์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. JWT ๊ตฌ์กฐ

JWT๋Š” Header.Payload.Signature ํ˜•ํƒœ์˜ ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

xxxxx.yyyyy.zzzzz

๊ตฌ์„ฑ ์š”์†Œ์„ค๋ช…
Header์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ •๋ณด(HS256, RS256 ๋“ฑ) + ํƒ€์ž…(JWT)
Payload์‚ฌ์šฉ์ž ์ •๋ณด(์˜ˆ: id, email, role) + ๋งŒ๋ฃŒ ์‹œ๊ฐ„(exp)
SignatureHeader + Payload๋ฅผ ๋น„๋ฐ€ํ‚ค๋กœ ์„œ๋ช…ํ•˜์—ฌ ๋ณ€์กฐ ๋ฐฉ์ง€

์˜ˆ์‹œ (๋””์ฝ”๋”ฉ ํ›„):

{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "id": 1,
  "username": "seunghyeok",
  "exp": 1692897200
}

2. JWT ๋™์ž‘ ๊ณผ์ •

  1. ๋กœ๊ทธ์ธ ์š”์ฒญ โ†’ ์‚ฌ์šฉ์ž๊ฐ€ ID/PW๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌ

  2. ํ† ํฐ ๋ฐœ๊ธ‰ โ†’ ์„œ๋ฒ„๊ฐ€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ํ™•์ธ ํ›„ JWT ์ƒ์„ฑ, ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌ

  3. ์ธ์ฆ ์š”์ฒญ โ†’ ํด๋ผ์ด์–ธํŠธ๊ฐ€ API ์š”์ฒญ ์‹œ Authorization: Bearer ํ—ค๋”์— ๋‹ด์•„ ์ „๋‹ฌ

  4. ์„œ๋ฒ„ ๊ฒ€์ฆ โ†’ ์„œ๋ฒ„๋Š” ๋น„๋ฐ€ํ‚ค๋กœ JWT ์„œ๋ช…(Signature) ๊ฒ€์ฆ ํ›„ ๊ถŒํ•œ ์ฒดํฌ

  5. ์‘๋‹ต โ†’ ์ •์ƒ ์š”์ฒญ์ด๋ฉด ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜

๐Ÿ‘‰ ์„ธ์…˜/์ฟ ํ‚ค ๊ธฐ๋ฐ˜ ์ธ์ฆ๊ณผ ๋‹ฌ๋ฆฌ ์„œ๋ฒ„๊ฐ€ ์ƒํƒœ(state)๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Stateless ์ธ์ฆ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

3. JWT์˜ ์žฅ์ 

  • Stateless: ์„œ๋ฒ„์— ์„ธ์…˜ ์ €์žฅ์†Œ๊ฐ€ ํ•„์š” ์—†์Œ

  • ํ™•์žฅ์„ฑ: ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค, ๋‹ค๋ฅธ ๋„๋ฉ”์ธ ๊ฐ„ ์ธ์ฆ์— ์šฉ์ด

  • ๋ณดํŽธ์„ฑ: OAuth2, OpenID Connect ๋“ฑ ๋‹ค์–‘ํ•œ ์ธ์ฆ ํ‘œ์ค€์—์„œ ํ™œ์šฉ

4. JWT์˜ ๋‹จ์ 

  • ํ† ํฐ ํฌ๊ธฐ: Payload์— ๋งŽ์€ ์ •๋ณด๋ฅผ ๋„ฃ์œผ๋ฉด ํฌ๊ธฐ๊ฐ€ ์ปค์ง โ†’ ๋„คํŠธ์›Œํฌ ๋ถ€๋‹ด

  • ๋ฌดํšจํ™” ์–ด๋ ค์›€: ๋ฐœ๊ธ‰๋œ ํ† ํฐ์€ ๋งŒ๋ฃŒ ์ „๊นŒ์ง€ ์œ ํšจ โ†’ ๊ฐ•์ œ ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ ์–ด๋ ค์›€

  • ๋ณด์•ˆ ์ทจ์•ฝ์„ฑ: ํ† ํฐ ํƒˆ์ทจ ์‹œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ โ†’ ๋ฐ˜๋“œ์‹œ HTTPS ํ•„์š”

    ๐Ÿ’ก ๋ณด์•ˆ ๊ณ ๋ ค์‚ฌํ•ญ

    • ํ† ํฐ ์ €์žฅ ์œ„์น˜
      • localStorage: ๊ฐ„๋‹จํ•˜์ง€๋งŒ XSS ๊ณต๊ฒฉ์— ์ทจ์•ฝ
      • HttpOnly Cookie: ๋ณด์•ˆ์„ฑ โ†‘, ํ•˜์ง€๋งŒ CORS ์„ค์ • ํ•„์š”
    • ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์„ค์ •
      • Access Token ์งง๊ฒŒ, Refresh Token ๊ธธ๊ฒŒ โ†’ ์žฌ๋ฐœ๊ธ‰ ์ „๋žต ํ•„์š”
    • HTTPS ํ•„์ˆ˜
      • ํ‰๋ฌธ ์ „์†ก ์‹œ ํ† ํฐ ํƒˆ์ทจ ์œ„ํ—˜

5. JWT์˜ ํ™œ์šฉ ์˜ˆ์‹œ

  • ์›น/๋ชจ๋ฐ”์ผ ๋กœ๊ทธ์ธ ์ธ์ฆ

  • OAuth2 ๊ธฐ๋ฐ˜ SNS ๋กœ๊ทธ์ธ (๊ตฌ๊ธ€, ๋„ค์ด๋ฒ„, ์นด์นด์˜ค)

  • API ์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹  ์ธ์ฆ (Microservice ํ™˜๊ฒฝ)

  • Refresh Token ์ „๋žต์œผ๋กœ ์žฅ๊ธฐ ์„ธ์…˜ ์œ ์ง€


๐Ÿ“—์ •๋ฆฌ

JWT๋Š” ํ˜„๋Œ€ ์›น ์„œ๋น„์Šค์—์„œ ์ธ์ฆ์˜ ํ•ต์‹ฌ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋งŒ๋Šฅ์€ ์•„๋‹ˆ๋ฉฐ, ์ ์ ˆํ•œ ๋งŒ๋ฃŒ ์ •์ฑ…, ์ €์žฅ ์ „๋žต, Refresh Token ์šด์šฉ ๋“ฑ์„ ํ•จ๊ป˜ ๊ณ ๋ คํ•ด์•ผ ์•ˆ์ „ํ•œ ์ธ์ฆ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

profile
Full-Stack Developer

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