[Server] JWT(Json Web Token)

๐Ÿ”น JWT๋ž€ ?

  • JWT(Json Web Token)์ด๋ž€, JSON ํฌ๋งท์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” Claim ๊ธฐ๋ฐ˜์˜ Web ํ† ํฐ์ด๋‹ค.
  • JWT๋Š” ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ž์ฒด์ ์œผ๋กœ ์ง€๋‹ˆ๋Š” Self-Contained ๋ฐฉ์‹์œผ๋กœ ์ •๋ณด๋ฅผ ์•ˆ์ •์„ฑ ์žˆ๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค.

 

๐Ÿ”น JWT ๊ตฌ์„ฑ

JWT๋Š” ์œ„์™€ ๊ฐ™์ด Header, Payload, Signature ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

๊ฐ๊ฐ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” .์„ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„๋˜๋ฉฐ, Json์œผ๋กœ ํฌ๋งท๋œ ๊ฐ ๋ถ€๋ถ„์€ Base64๋กœ ์ธ์ฝ”๋”ฉ ๋˜์–ด ํ‘œํ˜„๋œ๋‹ค.

 

[ Header (ํ—ค๋”) ]

  • alg์™€ typ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • alg : ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜, ์„œ๋ช…(Signature) ๋ฐ ํ† ํฐ ๊ฒ€์ฆ์— ์‚ฌ์šฉ๋œ๋‹ค. (์„œ๋ช…์„ ํ•ด์‹ฑํ•˜๊ธฐ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ง€์ •)
  • typ : ํ† ํฐ์˜ ํƒ€์ž…

[ Payload (ํŽ˜์ด๋กœ๋“œ) ]

  • ํ† ํฐ์—์„œ ์‚ฌ์šฉํ•  ์ •๋ณด์˜ ์กฐ๊ฐ๋“ค์ธ ํด๋ ˆ์ž„(Claim)์ด ๋‹ด๊ฒจ์žˆ๋‹ค.
  • ํด๋ ˆ์ž„์€ ๋“ฑ๋ก๋œ ํด๋ ˆ์ž„(Registered Claim), ๊ณต๊ฐœ ํด๋ ˆ์ž„(Pubilic Claim), ๋น„๊ณต๊ฐœ ํด๋ ˆ์ž„(Private Claim)์œผ๋กœ ๋‚˜๋ˆ„์–ด์ง€๋ฉฐ, key-value ํ˜•ํƒœ๋กœ ์กด์žฌํ•œ๋‹ค.

โ—ฝ ๋“ฑ๋ก๋œ ํด๋ ˆ์ž„ (Registered Claim)

๋“ฑ๋ก๋œ ํด๋ ˆ์ž„์€ ํ† ํฐ ์ •๋ณด๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฏธ ์ •ํ•ด์ง„ ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋“ค๋กœ, ๋ชจ๋‘ ์„ ํƒ์ ์œผ๋กœ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•˜์—ฌ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

  • iss : ํ† ํฐ ๋ฐœ๊ธ‰์ž(issuer)
  • sub : ํ† ํฐ ์ œ๋ชฉ(subject), unique ํ•  ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค. (์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ)
  • aud : ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ๊ฐ„(expiration), ์‹œ๊ฐ„์€ NumericDate ํ˜•์‹(1480849147370)์œผ๋กœ ๋˜์–ด์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ์–ธ์ œ๋‚˜ ํ˜„์žฌ ์‹œ๊ฐ„๋ณด๋‹ค ์ดํ›„๋กœ ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • nbf : ํ† ํฐ ํ™œ์„ฑ ๋‚ ์งœ(not before), ๋‚ ์งœ๋Š” NumericDate ํ˜•์‹(1480849147370)์œผ๋กœ ๋˜์–ด์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ์„ค์ •๋œ ๋‚ ์งœ๊ฐ€ ์ง€๋‚˜์ง€ ์ „๊นŒ์ง€๋Š” ํ† ํฐ์ด ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • iat : ํ† ํฐ ๋ฐœ๊ธ‰ ์‹œ๊ฐ„(issued at), ํ† ํฐ ๋ฐœ๊ธ‰ ์ดํ›„์˜ ๊ฒฝ๊ณผ ์‹œ๊ฐ„
  • jti : JWT ํ† ํฐ ์‹๋ณ„์ž(JWT ID), ์ค‘๋ณต ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์—ฌ, ์ผํšŒ์šฉ ํ† ํฐ(Access Token) ๋“ฑ์— ์‚ฌ์šฉ๋œ๋‹ค.

โ—ฝ ๊ณต๊ฐœ ํด๋ ˆ์ž„ (Pubilic Claim)

๊ณต๊ฐœ ํด๋ ˆ์ž„์€ ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ ˆ์ž„์œผ๋กœ, ๊ณต๊ฐœ์šฉ ์ •๋ณด๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

์ถฉ๋Œ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด URI ํฌ๋งท์„ ์ด์šฉํ•œ๋‹ค.

{
   "https://je0ng-dev-log.tistory.com": true
}

โ—ฝ ๋น„๊ณต๊ฐœ ํด๋ ˆ์ž„(Private Claim)

๋น„๊ณต๊ฐœ ํด๋ ˆ์ž„์€ ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ ˆ์ž„์œผ๋กœ, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด์— ์ž„์˜๋กœ ์ง€์ •ํ•œ ์ •๋กœ๋ฅผ ์ €์žฅํ•œ๋‹ค.

{
   "access_token": access
}

 

[ Signature (์„œ๋ช…) ]

  • ํ† ํฐ์„ ์ธ์ฝ”๋”ฉํ•˜๊ฑฐ๋‚˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ณ ์œ ํ•œ ์•”ํ˜ธํ™” ์ฝ”๋“œ์ด๋‹ค.
  • ์„œ๋ช…์€ ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ, ๋น„๋ฐ€ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ๋˜๋ฉฐ, ํ•ด๋‹น ํ† ํฐ์ด ๋ณ€์กฐ๋˜์ง€ ์•Š์•˜์Œ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด๋‹ค.
  • ์„œ๋ช… ์ƒ์„ฑ ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    1. ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ์˜ ๊ฐ’์„ ๊ฐ๊ฐ BASE64๋กœ ์ธ์ฝ”๋”ฉ
    2. ์ธ์ฝ”๋”ฉํ•œ ๊ฐ’์„ ๋น„๋ฐ€ ํ‚ค๋ฅผ ์ด์šฉํ•ด ํ—ค๋”์—์„œ ์ •์˜ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํ•ด์‹ฑ
    3. ํ•ด์‹ฑํ•œ ๊ฐ’์„ ๋‹ค์‹œ BASE64๋กœ ์ธ์ฝ”๋”ฉํ•˜์—ฌ ์ƒ์„ฑ

 

๐Ÿ”น JWT ์žฅ๋‹จ์ 

์žฅ์ 

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

๋‹จ์ 

  • ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํ† ํฐ์ด ์ฟ ํ‚ค ๋˜๋Š” ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€, ์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋˜๋ฏ€๋กœ ํƒˆ์ทจ๋‹นํ•  ์œ„ํ—˜์ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ token์— ์ค‘์š” ์ •๋ณด๋ฅผ ํฌํ•จํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.
  • ํ† ํฐ์— ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ํ† ํฐ์ด ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๋ฉฐ, API ํ˜ธ์ถœ ์‹œ๋งˆ๋‹ค ์ด๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋„คํŠธ์›Œํฌ ๋Œ€์—ญํญ์„ ๋‚ญ๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•œ๋ฒˆ ๋ฐœ๊ธ‰๋œ token์€ ์ˆ˜์ •์ด๋‚˜ ํ๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
    • Access token์˜ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์งง๊ฒŒ ์„ค์ •ํ•˜๊ณ , Refresh token์„ ์‚ฌ์šฉํ•˜์—ฌ Access token์„ ์ฃผ๊ธฐ์ ์œผ๋กœ ์žฌ๋ฐœ๊ธ‰ํ•จ์œผ๋กœ์จ, Access token์ด ํƒˆ์ทจ๋˜๋”๋ผ๋„ ํ•ด์ปค๊ฐ€ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ”ธ Redis (์ฐธ๊ณ )

๐Ÿค” Redis ์‚ฌ์šฉ ?

  • ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค ํ† ํฐ์„ ๊ฒ€์ฆํ•ด์•ผ ํ•œ๋‹ค.
  • ์ด๋•Œ, Redis๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ† ํฐ ๋น ๋ฅด๊ฒŒ ๊ฒ€์ฆํ•˜๊ณ , ํ† ํฐ์ด ํƒˆ์ทจ๋  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿค” Redis์— refreshToken๋งŒ ์ €์žฅ ?

  • Redis์— refreshToken๋งŒ ์ €์žฅํ•จ์œผ๋กœ์จ, ํ† ํฐ์ด ํƒˆ์ทจ๋˜๊ฑฐ๋‚˜ ์•…์šฉ๋  ๊ฒฝ์šฐ, ์„œ๋ฒ„ ์ธก์—์„œ ํ•ด๋‹น refreshToken์„ ๋ฌดํšจํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค.
    • ๋ณด์•ˆ : accessToken์ด ํƒˆ์ทจ๋˜๋”๋ผ๋„ refreshToken์ด ์—†๋‹ค๋ฉด ์ƒˆ๋กœ์šด accessToken์„ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—,  refreshToken์„ Redis์— ์ €์žฅํ•˜๋ฉด ๋ณด์•ˆ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
    • ํ† ํฐ ์žฌ๋ฐœ๊ธ‰ ๊ด€๋ฆฌ : accessToken์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ, ์„œ๋ฒ„๋Š” Redis์— ์ €์žฅ๋œ refreshToken๊ณผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ด๋Š” refreshToken์„ ๋น„๊ตํ•˜์—ฌ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๊ณ , ์ƒˆ๋กœ์šด accessToken์„ ์žฌ๋ฐœ๊ธ‰ํ•œ๋‹ค.

๐Ÿค” refreshToken ๋งŒ๋ฃŒ ?

  • Redis์˜ TTL(Time To Live) ์„ค์ •์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • refreshToken์ด ๋งŒ๋ฃŒ๋˜๋ฉด, ์‚ฌ์šฉ์ž๋Š” ์žฌ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด accessToken๊ณผ refreshToken์„ ๋ฐœ๊ธ‰๋ฐ›๊ฒŒ ๋œ๋‹ค.
  • ์ด๋•Œ, ์ƒˆ๋กœ์šด refreshToken์€ Redis์— ์ €์žฅ๋˜๋ฉฐ, ๊ธฐ์กด refreshToken์€ ์ž๋™์œผ๋กœ ๋งŒ๋ฃŒ๋œ๋‹ค.

 

 

 

 

 

 

๐Ÿ“ƒ reference