๐Ÿ” JWT(Json Web Token): ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ์กฐ์‹ฌํ•ด์•ผ ํ•  ์ธ์ฆ ๋ฐฉ์‹

์„ํ˜„ยท2025๋…„ 2์›” 19์ผ
0

Insight

๋ชฉ๋ก ๋ณด๊ธฐ
22/43

๐Ÿ” JWT(Json Web Token): ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ์กฐ์‹ฌํ•ด์•ผ ํ•  ์ธ์ฆ ๋ฐฉ์‹

๐Ÿค” JWT๊ฐ€ ๋ญ๊ธธ๋ž˜?

์ตœ๊ทผ Google CASA ์ธ์ฆ์„ ๋ฐ›์œผ๋ฉด์„œ JWT๋ฅผ ํ•ด๋ช…(?)ํ•ด์•ผํ•  ์ผ์ด ๋งŽ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค ๋ณด๋‹ˆ '์ด๊ฑฐ ํ•œ ๋ฒˆ ์ œ๋Œ€๋กœ ์ •๋ฆฌํ•ด์•ผ๊ฒ ๋‹ค'๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค JWT๋Š” ๋งŽ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ, ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋ฉด ๋ณด์•ˆ์ ์œผ๋กœ ํฐ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค๋”๊ตฐ์š”. ๊ทธ๋ž˜์„œ ์˜ค๋Š˜์€ JWT๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€, ์™œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ๋ณด์•ˆ์ ์œผ๋กœ ์–ด๋–ค ์ ์„ ์ฃผ์˜ํ•ด์•ผ ํ•˜๋Š”์ง€ ํ•œ ๋ฒˆ์— ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! ๐Ÿš€


๐Ÿ” JWT์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ

JWT๋Š” 3๊ฐ€์ง€ ํŒŒํŠธ๋กœ ๊ตฌ์„ฑ๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ์ (.)์œผ๋กœ ๊ตฌ๋ถ„๋˜๋ฉฐ, ๊ฐ๊ฐ ํ—ค๋”(Header), ํŽ˜์ด๋กœ๋“œ(Payload), ์„œ๋ช…(Signature)์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1๏ธโƒฃ ํ—ค๋”(Header)

JWT์˜ ํ—ค๋”์—๋Š” ํ† ํฐ ํƒ€์ž…๊ณผ ์‚ฌ์šฉ๋œ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg: ์‚ฌ์šฉํ•  ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜(์˜ˆ: HS256, RS256)
  • typ: ํ† ํฐ ํƒ€์ž… (JWT)

2๏ธโƒฃ ํŽ˜์ด๋กœ๋“œ(Payload)

JWT์˜ ํŽ˜์ด๋กœ๋“œ์—๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด์™€ ํ† ํฐ์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ๋“ฑ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
  • sub: ํ† ํฐ์˜ ์ฃผ์ธ (Subject)
  • name: ์‚ฌ์šฉ์ž ์ด๋ฆ„
  • iat: ํ† ํฐ์ด ๋ฐœ๊ธ‰๋œ ์‹œ๊ฐ„ (Issued At)

๐Ÿ“Œ ์ฃผ์˜: JWT๋Š” Base64๋กœ ์ธ์ฝ”๋”ฉ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ˆ„๊ตฌ๋“ ์ง€ ๋””์ฝ”๋”ฉํ•ด์„œ ๋‚ด์šฉ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ ˆ๋Œ€ ํฌํ•จํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค!

3๏ธโƒฃ ์„œ๋ช…(Signature)

์„œ๋ช…(Signature)์€ JWT์˜ ๋ฌด๊ฒฐ์„ฑ(Integrity)์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ† ํฐ์ด ์ค‘๊ฐ„์— ์กฐ์ž‘๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

์„œ๋ช… ๋ถ€๋ถ„์ด ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด, ํ† ํฐ์ด ๋ณ€์กฐ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ ์ธ์ฆ์ด ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.


๐ŸŽฏ JWT๊ฐ€ ์™œ ์ด๋ ‡๊ฒŒ ์ธ๊ธฐ์ผ๊นŒ?

JWT๊ฐ€ ์ธ๊ธฐ ์žˆ๋Š” ์ด์œ ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•˜๊ธฐ ํŽธ๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

1๏ธโƒฃ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š” ์—†์Œ

JWT๋Š” ์„œ๋ฒ„๊ฐ€ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋”ฐ๋กœ ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „ ๋ฐฉ์‹์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์„ธ์…˜์„ ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด, ํŠธ๋ž˜ํ”ฝ์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ์„œ๋ฒ„ ๋ถ€๋‹ด์ด ์ปค์ง€๊ณ , ๋ถ€ํ•˜ ๋ถ„์‚ฐ์„ ์œ„ํ•ด ์„ธ์…˜ ๊ณต์œ (Sticky Session) ๊ฐ™์€ ๊ฑธ ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๊ฒŒ ๊ฝค๋‚˜ ๊ท€์ฐฎ์Šต๋‹ˆ๋‹ค... ํ•˜์ง€๋งŒ JWT๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ์ธ์ฆ ์ •๋ณด๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์—์„œ๋Š” ์ด๊ฑธ ํ™•์ธ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ™•์žฅ์„ฑ(Scale-Out)์— ๊ฐ•ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ ๋น ๋ฆ„

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

3๏ธโƒฃ ์–ธ์–ด์™€ ํ”Œ๋žซํผ์— ๊ด€๊ณ„์—†์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ

JWT๋Š” JSON ํฌ๋งท์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›น๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋ฐ”์ผ ์•ฑ, ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜, ์„œ๋ฒ„ ๊ฐ„ ์ธ์ฆ ๋“ฑ ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ ์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Node.js, Python, Java, Go ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด์—์„œ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ธฐ์ˆ ์„ ์จ๋„ ๋ฌธ์ œ์—†์ด ์—ฐ๋™ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ํŽธํ•˜๋‹ค๊ณ  ๋งˆ๋ƒฅ ์ข‹์€ ๊ฑด ์•„๋‹ˆ๋‹ˆ๊นŒ! JWT๋ฅผ ์“ธ ๋•Œ ์กฐ์‹ฌํ•ด์•ผ ํ•  ์ ๋„ ๋งŽ์Šต๋‹ˆ๋‹ค.

โœ… 1. ์ƒํƒœ ์œ ์ง€ ํ•„์š” ์—†์Œ (Stateless Authentication)

JWT๋Š” ์„ธ์…˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ €์žฅํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

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

โœ… 2. ํ™•์žฅ์„ฑ(Scalability) ํ–ฅ์ƒ

JWT๋Š” ์„œ๋ฒ„ ๊ฐ„ ๊ณต์œ ๊ฐ€ ํ•„์š” ์—†๋Š” ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ๋„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

โœ… 3. ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

JWT๋Š” ์›น๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ชจ๋ฐ”์ผ ์•ฑ, ์„œ๋ฒ„ ๊ฐ„ ์ธ์ฆ, API ์ธ์ฆ์—๋„ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • OAuth2, OpenID Connect ๋“ฑ์—์„œ ํ‘œ์ค€ ์ธ์ฆ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ JWT ์‚ฌ์šฉํ•  ๋•Œ ์กฐ์‹ฌํ•ด์•ผ ํ•  ์ 

JWT๊ฐ€ ํŽธ๋ฆฌํ•œ ๋งŒํผ, ๋ณด์•ˆ์ ์œผ๋กœ ์‹ ๊ฒฝ ์จ์•ผ ํ•  ๋ถ€๋ถ„๋„ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋Œ€์ถฉ ์‚ฌ์šฉํ•˜๋ฉด ํฐ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋ฐ˜๋“œ์‹œ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1๏ธโƒฃ ํ† ํฐ์€ ๋””์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ๋‹ค (์•”ํ˜ธํ™” ์•„๋‹˜!)

JWT๋Š” Base64๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด ์žˆ์„ ๋ฟ, ์•”ํ˜ธํ™”๋œ ๊ฒŒ ์•„๋‹™๋‹ˆ๋‹ค. ์ฆ‰, ๋ˆ„๊ตฌ๋“ ์ง€ ํ† ํฐ์„ ๋””์ฝ”๋”ฉํ•ด์„œ ๋‚ด๋ถ€ ์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 ์ด๋Ÿฐ ๋ฌธ์ž์—ด์„ Base64 ๋””์ฝ”๋”ฉํ•˜๋ฉด ๋ฐ”๋กœ ์›๋ณธ JSON ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ ˆ๋Œ€ JWT์— ๋‹ด์ง€ ๋ง์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2๏ธโƒฃ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ๋ฐ˜๋“œ์‹œ ์„ค์ •ํ•˜์ž

JWT๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„์—์„œ ๋”ฐ๋กœ ์„ธ์…˜์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํ† ํฐ์ด ์œ ์ถœ๋˜๋ฉด ๋ˆ„๊ตฌ๋‚˜ ํ•ด๋‹น ํ† ํฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ exp(๋งŒ๋ฃŒ ์‹œ๊ฐ„)๋ฅผ ์„ค์ •ํ•ด์„œ ์œ ํšจ๊ธฐ๊ฐ„์„ ์งง๊ฒŒ ๋‘๋Š” ๊ฒƒ์ด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค! ์˜ˆ๋ฅผ ๋“ค์–ด, ๋กœ๊ทธ์ธ ํ† ํฐ์€ 30๋ถ„~1์‹œ๊ฐ„ ์ •๋„๋กœ ์„ค์ •ํ•˜๊ณ , Refresh Token์„ ๋ณ„๋„๋กœ ๋ฐœ๊ธ‰ํ•ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.

3๏ธโƒฃ 'none' ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ—ˆ์šฉํ•˜๋ฉด ์•ˆ ๋œ๋‹ค

JWT์˜ ํ—ค๋” ๋ถ€๋ถ„์„ ๋ณด๋ฉด alg(์•Œ๊ณ ๋ฆฌ์ฆ˜) ๊ฐ’์ด ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ alg: "none"์œผ๋กœ ์„ค์ •ํ•˜๋ฉด, ์„œ๋ช…์„ ๊ฒ€์ฆํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ํ†ต๊ณผ์‹œํ‚ค๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์„œ๋ฒ„์—์„œ ์ด๊ฑธ ํ—ˆ์šฉํ•˜๋ฉด, ๊ณต๊ฒฉ์ž๊ฐ€ ์„œ๋ช…์„ ์•„์˜ˆ ์ œ๊ฑฐํ•œ ํ† ํฐ์„ ๋งŒ๋“ค์–ด์„œ ์„œ๋ฒ„๋ฅผ ์†์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋ฐ˜๋“œ์‹œ none ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

4๏ธโƒฃ ํ† ํฐ ์ €์žฅ ๋ฐฉ์‹ ์ฃผ์˜ (XSS, CSRF ๊ณต๊ฒฉ ๋Œ€๋น„)

JWT๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ €์žฅํ•  ๋•Œ, ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€(localStorage)์— ์ €์žฅํ•˜๋ฉด XSS(Cross-Site Scripting) ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , Secure, HttpOnly ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด XSS ๊ณต๊ฒฉ์„ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ CSRF(Cross-Site Request Forgery) ๊ณต๊ฒฉ์— ๋Œ€๋น„ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, CSRF ํ† ํฐ์„ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

JWT๋Š” ๊ฐ•๋ ฅํ•œ ์ธ์ฆ ๋ฐฉ์‹์ด์ง€๋งŒ, ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋ฉด ๋ณด์•ˆ์ƒ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌํ•ญ์„ ๋ฐ˜๋“œ์‹œ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

โŒ 1. ๋ฏผ๊ฐํ•œ ์ •๋ณด ํฌํ•จ ๊ธˆ์ง€

JWT๋Š” Base64 ์ธ์ฝ”๋”ฉ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋ˆ„๊ตฌ๋‚˜ ๋””์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

base64 -d eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9

โžก ๊ฒฐ๋ก : ๋น„๋ฐ€๋ฒˆํ˜ธ, ์นด๋“œ ๋ฒˆํ˜ธ, ๊ฐœ์ธ์ •๋ณด ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ ˆ๋Œ€ ํฌํ•จํ•˜์ง€ ๋งˆ์„ธ์š”!

โŒ 2. ํ† ํฐ ์ €์žฅ ์œ„์น˜ (XSS ๊ณต๊ฒฉ ๋Œ€๋น„)

  • JWT๋ฅผ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€(localStorage)์— ์ €์žฅํ•˜๋ฉด XSS(Cross-Site Scripting) ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋  ์œ„ํ—˜์ด ํฝ๋‹ˆ๋‹ค.
  • Secure HttpOnly Cookie๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

โŒ 3. ์ ์ ˆํ•œ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์„ค์ •

  • JWT๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ธ์…˜์„ ์œ ์ง€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํ† ํฐ์ด ์œ ์ถœ๋˜๋ฉด ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ์‚ฌ๊ณ ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ JWT์˜ exp(๋งŒ๋ฃŒ ์‹œ๊ฐ„)๋ฅผ ์งง๊ฒŒ ์„ค์ •ํ•˜๊ณ , ํ•„์š”ํ•  ๊ฒฝ์šฐ Refresh Token์„ ํ™œ์šฉํ•˜์—ฌ ์žฌ๋ฐœ๊ธ‰ํ•˜๋Š” ๋ฐฉ์‹์ด ์ข‹์Šต๋‹ˆ๋‹ค.

โŒ 4. 'none' ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ณต๊ฒฉ ์ฃผ์˜

  • ์ผ๋ถ€ JWT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” alg: "none" ์„ค์ •์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณต๊ฒฉ์ž๊ฐ€ ์„œ๋ช… ๊ฒ€์ฆ์„ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•ด alg: "none"์„ ์„ค์ •ํ•˜์—ฌ ์„œ๋ช… ์—†์ด๋„ ์œ ํšจํ•œ JWT๋กœ ์ธ์‹๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐ˜๋“œ์‹œ none ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋„๋ก ์„œ๋ฒ„ ์„ค์ •์„ ํ™•์ธํ•˜์„ธ์š”!

๐Ÿš€ ์ •๋ฆฌ: JWT, ์ด๋ ‡๊ฒŒ ์“ฐ๋ฉด ์•ˆ์ „ํ•˜๋‹ค!

JWT๋Š” ํ™•์‹คํžˆ ํŽธ๋ฆฌํ•œ ์ธ์ฆ ๋ฐฉ์‹์ด์ง€๋งŒ, ๋ณด์•ˆ์ ์œผ๋กœ ์‹ ๊ฒฝ ์จ์•ผ ํ•  ๋ถ€๋ถ„์ด ๋งŽ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ ์•ˆ์ „ํ•˜๊ฒŒ JWT๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด?

  • ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ์ ˆ๋Œ€ JWT์— ๋‹ด์ง€ ๋ง ๊ฒƒ!
  • ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์งง๊ฒŒ ์„ค์ •ํ•˜๊ณ , Refresh Token์„ ํ™œ์šฉํ•  ๊ฒƒ
  • ์„œ๋ฒ„์—์„œ 'none' ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋„๋ก ํ™•์ธํ•  ๊ฒƒ
  • JWT๋ฅผ ์ €์žฅํ•  ๋•Œ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ๋Œ€์‹  Secure HttpOnly ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

JWT๋Š” ๊ฐ•๋ ฅํ•˜๊ณ  ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚œ ์ธ์ฆ ๋ฐฉ์‹์ด์ง€๋งŒ, ๋ณด์•ˆ์ ์œผ๋กœ ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ๋Š” ์š”์†Œ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ์›์น™์„ ๊ผญ ์ง€์ผœ์ฃผ์„ธ์š”! โœ…

โœ” ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ์ ˆ๋Œ€ ํฌํ•จํ•˜์ง€ ๋ง ๊ฒƒ
โœ” ํ† ํฐ์„ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ , Secure HttpOnly Cookie๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ
โœ” ์ ์ ˆํ•œ ๋งŒ๋ฃŒ ์‹œ๊ฐ„(exp)์„ ์„ค์ •ํ•˜๊ณ , Refresh Token์„ ํ™œ์šฉํ•  ๊ฒƒ
โœ” ์„œ๋ฒ„์—์„œ none ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•  ๊ฒƒ
โœ” ๋น„๋ฐ€ ํ‚ค(Secret Key)๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ๊ฒƒ

์ด์ œ JWT์— ๋Œ€ํ•ด ๋” ๊นŠ์ด ์ดํ•ดํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉํ•ด ๋ณด์„ธ์š”! ๐Ÿš€

๋‹ค์Œ์—๋Š” CASA Tier2๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•œ ์ธ์ฆ ๊ณผ์ •๋„ ์ •๋ฆฌํ•ด์„œ ์˜ฌ๋ ค๋ณด๊ฒ ๋‹ค. ์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ˜‰ ๋‹ค์Œ์—๋Š” CASA Tier2 ์ธ์ฆ ๊ณผ์ •๋„ ์ •๋ฆฌํ•ด๋ณผ ์˜ˆ์ •์ด๋‹ˆ ๊ธฐ๋Œ€ํ•ด ์ฃผ์„ธ์š”!

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