Archive for Dev. (junyup2)

์ง€์‹์„ ์ฑ„์›Œ๊ฐ€๋Š” ใ€Ž๊ฐœ๋ฐœ์ž/ํ™”์ดํŠธํ•ด์ปคใ€๋ฅผ ๋ชฉํ‘œ๋กœ ์ •๋ฆฌํ•˜๋Š” ๋ธ”๋กœ๊ทธ

๋ชจ์˜ ํ•ดํ‚น ์Šคํ„ฐ๋””/๋ชจ์˜ ํ•ดํ‚น - ๊ณผ์ œ

[๊ณผ์ œ] 03์ฃผ์ฐจ(3) - JWT ๋ž€?

Gearvirus(junyup2) 2023. 11. 8. 23:51

JWT ์— ๋Œ€ํ•œ ์ดํ•ด

 

์ด์ „ ๊ธ€์—์„œ ์ด์–ด์ง€๋Š” ๋‚ด์šฉ

๋ชจ์˜ ํ•ดํ‚น ์Šคํ„ฐ๋”” - ๊ธฐ๋ก์ผ์ง€ 03์ฃผ์ฐจ (๋กœ๊ทธ์ธ ๋กœ์ง/๋กœ๊ทธ์ธ ์œ ์ง€)

 

๋ชจ์˜ ํ•ดํ‚น ์Šคํ„ฐ๋”” - ๊ธฐ๋ก์ผ์ง€ 03์ฃผ์ฐจ (๋กœ๊ทธ์ธ ๋กœ์ง/๋กœ๊ทธ์ธ ์œ ์ง€)

๋กœ๊ทธ์ธ ๋กœ์ง(๋กœ๊ทธ์ธ ๊ณผ์ •)๊ณผ ๋กœ๊ทธ์ธ ์œ ์ง€ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ดํ•ด ๋กœ๊ทธ์ธ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€? ๋‹ค์ค‘ ์‚ฌ์šฉ์ž ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์ปดํ“จํ„ฐ์— ์‚ฌ์šฉ์ž์ž„์„ ์•Œ๋ฆฌ๋Š”์ผ (์ฆ‰, ์ปดํ“จํ„ฐ๊ฐ€ ๊ทธ ์‚ฌ๋žŒ์ด ๋งž๋Š”์ง€๋ฅผ ํ™•์ธ

codegear-archive.tistory.com

 

์™œ JWT์ผ๊นŒ?

 

์•ž์„œ ๋ณด์•˜๋“ฏ์ด ์ธ์ฆ์„ ์œ„ํ•ด Cookie์™€ Session์„ ์‚ฌ์šฉํ•˜๊ณ , ๊ทธ ํ•œ๊ณ„์ , ๋ณด์•ˆ์„ฑ์˜ ๋ฌธ์ œ๊ฐ€ ์กด์žฌ

์ฟ ํ‚ค์™€ ์„ธ์…˜์˜ ๋‹จ์ ์— ๋Œ€ํ•˜์—ฌ ์ข€ ๋” ์‚ดํŽด ๋ณด์ž๋ฉด...


์ฟ ํ‚ค(Cookie)

๋กœ๊ทธ์ธ ํ–ˆ์„ ๋•Œ Set-Cookie์˜ ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜์„ ๋ฐ›์€ ์ฟ ํ‚ค๋ฅผ ํ† ๋Œ€๋กœ ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•œ ์š”์ฒญ๋งˆ๋‹ค ์ฟ ํ‚ค๋ฅผ ๋˜์ ธ ๋™์ž‘

(์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” ์–ด๋–ค ํŠน์ • ์ •๋ณด๋ฅผ ์ €์žฅํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ, ๋งค๋ฒˆ ์š”์ฒญ๋งˆ๋‹ค ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์ •๋ณด๋ฅผ ๋‚ ๋ ค์•ผํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์„ ๋ง‰๊ธฐ ์œ„ํ•ด)

 

ํ•˜์ง€๋งŒ ๋งŽ์€ ๋‹จ์ ์ด ์กด์žฌ

  • ์ฟ ํ‚ค๋Š” ๋…ธ์ถœ๋˜์—ˆ์„๋•Œ id, pw์™€ ๊ฐ™์€ ๋ฏผ๊ฐ ์ •๋ณด๊นŒ์ง€ ๋‹ค ๋…ธ์ถœ๋˜์–ด ๋ณด์•ˆ์ด ์ข‹์ง€ ๋ชปํ•จ
  • ์กฐ์ž‘๋‹นํ•ด์„œ ๋“ค์–ด์˜ฌ ๊ฐ€๋Šฅ์„ฑ์ด ์กด์žฌ
  • ์›น ๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค ์ฟ ํ‚ค์— ๋Œ€ํ•œ ์ง€์› ํ˜•ํƒœ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋ธŒ๋ผ์šฐ์ €๊ฐ„์˜ ๊ณต์œ ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ
  • ์ฟ ํ‚ค์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ œํ•œ(4KB)๋˜์–ด ์žˆ์–ด ์›ํ•˜๋Š” ๋งŒํผ์˜ ์ถฉ๋ถ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌ
  • ์„œ๋ฒ„๋Š” ๋งค๋ฒˆ id, pw๋ฅผ ๋ฐ›์•„์„œ ์ธ์ฆํ•ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์กด์žฌ
    • (๋˜ํ•œ ์กฐ์ž‘๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋„˜์–ด์˜ค๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์—†์Œ)

 

์œ„์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ณ ์ž ์ฟ ํ‚ค(Cookie)์™€ ํ•จ๊ป˜ ์„ธ์…˜(Session)์„ ์‚ฌ์šฉ


์ฟ ํ‚ค(Cookie) &์„ธ์…˜(Session)

๋ฌด์–ธ๊ฐ€์— ๋Œ€ํ•œ ํŠน์ • ์ธ์ฆ ์ •๋ณด๋ฅผ ์„œ๋ฒ„๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๊ทธ ๊ฐ’์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜์—ฌ ์ธ์ฆ

(๋งˆ์น˜ ํ‚ค๋ฅผ ์ฃผ๊ณ  ์ž๋ฌผ์‡ ๋ฅผ ์—ฌ๋Š” ๋ฐฉ์‹) - ์„ธ์…˜ ID๋ฅผ ํŠน์ • ์ €์žฅ์†Œ์— ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉ

 

  • ๊ฐœ์ธ ๋ฏผ๊ฐ์ •๋ณด๋ฅผ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœํ–ˆ์„ ๋•Œ์˜ ๋‹จ์ ์„ ๋ง‰์•„๋‚ด๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ๊ฒƒ์ด ๋ฐ”๋กœ ์„ธ์…˜(Session)
  • ์ฟ ํ‚ค์•ˆ์— ๋„ฃ์–ด์„œ ๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ์ฟ ํ‚ค๋ผ๋Š” ์ •๋ณด ์ž์ฒด๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์Œ
    • (id, pw์™€ ๊ฐ™์€ ๋ฏผ๊ฐ์ •๋ณด๋ฅผ ๋‹ค๋ฃจ๋Š” ์ƒํ™ฉ์—์„œ์˜ ๋ณด์™„์ ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ๊ฒƒ)
  • ์ฟ ํ‚ค์™€ ๊ฐ™์€ ๋งค๊ฐœ์ฒด๋ฅผ ์ฃผ๊ณ  ๋ฐ›์Œ์œผ๋กœ์จ ๋งค๋ฒˆ ๋กœ๊ทธ์ธ ์‹œ id, pw๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์ „๋‹ฌํ•ด์•ผํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์„ ๋ณด์™„
  • id, pw๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์ธ์ฆ ์ •๋ณด ์ž์ฒด๋ฅผ ํŠน์ • ์„ธ์…˜ ์ €์žฅ์†Œ์— ์ €์žฅํ•˜๊ณ ,
  • ์ด ๊ฐ’์„ ์ฟ ํ‚ค์— ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฟ ํ‚ค๋ฅผ ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค ์„ธ์…˜ ์ €์žฅ์†Œ์— ์žˆ๋Š” ์ •๋ณด๋ž‘ ๋™์ผํ•œ์ง€๋กœ ๋กœ๊ทธ์ธ์„ ํ™•์ธํ•˜์ž๋Š” ๊ฒƒ
์„ธ์…˜์„ ์ด์šฉํ•œ ์ธ์ฆ ์ ˆ์ฐจ

1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ id / pw๋กœ ์„œ๋ฒ„์— ๋กœ๊ทธ์ธ ์š”์ฒญ์„ ํ•จ
2. id / pw๋กœ ์ธ์ฆ ํ›„ ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•  ํŠน์ • ์œ ๋‹ˆํฌํ•œ ์„ธ์…˜ ID๋ฅผ ๋งŒ๋“ค์–ด ์„œ๋ฒ„์˜ ์„ธ์…˜ ์ €์žฅ์†Œ์— ์ €์žฅ
3. ์„ธ์…˜ ID๋ฅผ ํŠน์ •ํ•œ ํ˜•ํƒœ(์ฟ ํ‚ค or json)๋กœ ํด๋ผ์ด์–ธํŠธ์— ๋‹ค์‹œ ๋ฐ˜ํ™˜
4. ์‚ฌ์šฉ์ž ์ธ์ฆ์ด ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค ์ด ์„ธ์…˜ ID๋ฅผ ์ฟ ํ‚ค์— ๋‹ด์•„ ์„œ๋ฒ„์— ํ•จ๊ป˜ ์ „๋‹ฌ
5. ์ธ์ฆ์ด ํ•„์š”ํ•œ api์˜ ๊ฒฝ์šฐ, ์„œ๋ฒ„๋Š” ์„ธ์…˜ ID๊ฐ€ ์„ธ์…˜ ์ €์žฅ์†Œ์— ์žˆ๋Š”์ง€ ํ™•์ธ
6. ์žˆ๋‹ค๋ฉด ์ธ์ฆ ์™„๋ฃŒ ํ›„ api ์ฒ˜๋ฆฌ, ์—†๋‹ค๋ฉด 401 ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜

 

  • ์ฟ ํ‚ค๋งŒ์„ ์ „์†กํ•  ๋•Œ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์„ธ์…˜ ์ €์žฅ์†Œ์— ์‹๋ณ„ ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ๋„ฃ์–ด๋‘๊ณ  ๊ทธ ๊ฐ’์ด ์ผ์น˜ํ–ˆ๋Š”์ง€๋งŒ ๋ณด๋ฉด ์ธ์ฆ์ด ๋˜๋‹ˆ ๋ณด์™„์ด ์กฐ๊ธˆ์€ ์˜ฌ๋ผ๊ฐ”๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Œ

 

  • ๋งŒ์•ฝ ๋ณด์•ˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ(ํƒˆ์ทจ ๋‹นํ•œ ์„ธ์…˜ ID) ํ•œ๋‹ค๋ฉด, ๊ทธ๋ƒฅ ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ ์ „๋ถ€ ์ง€์›Œ๋ฒ„๋ฆฌ๋ฉด ๋จ.
  • (์„ธ์…˜ ID๊ฐ€ ํƒˆ์ทจ๋‹นํ–ˆ์–ด๋„ ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ ์ „๋ถ€ ๋น„์šฐ๋ฉด, ํ•ด๋‹น ์„ธ์…˜ ID๋กœ ์„œ๋ฒ„์— ์ ‘๊ทผํ•ด๋„ ์ธ์ฆ๋  ์ˆ˜๋‹จ์ด ์—†์Œ)
  • BUT ๋‹ค๋ฅธ ๊ด€์ ์—์„œ ๋ณธ๋‹ค๋ฉด, ์„ธ์…˜ ์ €์žฅ์†Œ๊ฐ€ ๋ชจ์ข…์˜ ์ด์œ ๋กœ ์žฅ์• ๊ฐ€ ๋‚œ๋‹ค๋ฉด ์ธ์ฆ ์ „์ฒด์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ ์ •์ƒ์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ฆ์„ ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜๋„ ์žˆ์Œ
  • ๋˜ํ•œ HTTP์˜ ์žฅ์ ์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌด์ƒํƒœ์„ฑ(stateless)์„ ์œ„ํ•ด ์„œ๋ฒ„์˜ ์„ธ์…˜ ์ €์žฅ์†Œ์— ์„ธ์…˜ID, ์ฆ‰ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ์ƒํ™ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— stateful ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ

 

ํ•˜์—ฌ ์ฟ ํ‚ค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋งŽ์€ ๋‹จ์ ์ด ์กด์žฌ

  • ์„ธ์…˜ ์ €์žฅ์†Œ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ธ์ฆ ์ฒด๊ณ„๊ฐ€ ๋ฌด๋„ˆ์ ธ ์ด์ „์— ์ธ์ฆ๋œ ๋‹ค๋ฅธ ์œ ์ € ๋˜ํ•œ ์ธ์ฆ์ด ๋ถˆ๊ฐ€ํ•ด ์ง
  • stateful ํ•˜๊ธฐ ๋•Œ๋ฌธ์— http์˜ ์žฅ์ ์„ ๋ฐœํœ˜ ํ•˜์ง€ ๋ชปํ•จ scale out์— ๊ฑธ๋ฆผ๋Œ์ด ๋จ
    • (์™„์ „ํ•œ ๋ฌด์ƒํƒœ์„ฑ(stateless)์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์—†์Œ)
  • ์„ธ์…˜ ์ €์žฅ์†Œ๊ฐ€ ํ•„์ˆ˜์ ์œผ๋กœ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ž์›์ด ์†Œ๋ชจ๋จ
  • ์„ธ์…˜ ID๊ฐ€ ํƒˆ์ทจ๋˜์—ˆ์„ ๊ฒฝ์šฐ ๋Œ€์ฒ˜๋Š” ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ํด๋ผ์ด์–ธํŠธ ์ธ์ฒ™ ์œ„์žฅํ•˜๋Š” ๋ณด์•ˆ ์ทจ์•ฝ์ ์ด ์กด์žฌ
  • ์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€(๋งŽ์€ ์ž์›์„ ์†Œ๋ชจ)
  • ๋งค๋ฒˆ ์š”์ฒญ์‹œ ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ ์กฐํšŒํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ 
  • (์š”์ฒญ์„ ์ง„ํ–‰ํ•  ๋•Œ๋งˆ๋‹ค DB ์ ‘๊ทผ์ด๋ผ๋Š” ๋กœ์ง์ด ํ•œ๋ฒˆ ๋” ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ)

 

์œ„์™€ ๊ฐ™์€ ์ผ๋ จ์˜ ๊ณผ์ •(์ฟ ํ‚ค์™€ ์„ธ์…˜์˜ ํ•œ๊ณ„์ ) ์†์—์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ JWT

JWT ๋ž€? -  JSON ์›น ํ† ํฐ(JSON Web Token)

 

JSON Web Token (JWT) ์€ ์›นํ‘œ์ค€ (RFC 7519) ์œผ๋กœ์„œ, ๋‘ ๊ฐœ์ฒด์—์„œ JSON ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๋ณ๊ณ  ์ž๊ฐ€์ˆ˜์šฉ์ ์ธ (self-contained) ๋ฐฉ์‹์œผ๋กœ ์ •๋ณด๋ฅผ ์•ˆ์ „์„ฑ ์žˆ๊ฒŒ ์ „๋‹ฌ

  • (์„ ํƒ์  ์„œ๋ช… ๋ฐ ์„ ํƒ์  ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ธํ„ฐ๋„ท ํ‘œ์ค€ ์ธ์ฆ ๋ฐฉ์‹)
  • C, Java, Python, C++, R, C#, PHP, JavaScript, Ruby, Go, Swift ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ์ฃผ๋ฅ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์ง€์›
  • JWT ๋Š” ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์ž์ฒด์ ์œผ๋กœ ์ง€๋‹ˆ๊ณ  ์žˆ์Œ (= Self-contained)
    • JWT ์‹œ์Šคํ…œ์—์„œ ๋ฐœ๊ธ‰๋œ ํ† ํฐ์€, ํ† ํฐ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ์ •๋ณด, ์ „๋‹ฌ ํ•  ์ •๋ณด, ๊ทธ๋ฆฌ๊ณ  ํ† ํฐ์ด ๊ฒ€์ฆ๋๋‹ค๋Š”๊ฒƒ์„ ์ฆ๋ช…ํ•ด์ฃผ๋Š” signature ๋ฅผ ํฌํ•จ
  • JWT ๋Š” ์ž๊ฐ€์ˆ˜์šฉ์ ์ด๋ฏ€๋กœ, ๋‘ ๊ฐœ์ฒด ์‚ฌ์ด์—์„œ ์†์‰ฝ๊ฒŒ ์ „๋‹ฌ ๊ฐ€๋Šฅ
  • ์›น์„œ๋ฒ„์˜ ๊ฒฝ์šฐ HTTP์˜ ํ—ค๋”์— ๋„ฃ์–ด์„œ ์ „๋‹ฌ ํ•  ์ˆ˜๋„ ์žˆ๊ณ , URL ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ ํ•  ์ˆ˜๋„ ์žˆ์Œ

 

  • ํ† ํฐ์€ ๋น„๊ณต๊ฐœ ์‹œํฌ๋ฆฟ ํ‚ค ๋˜๋Š” ๊ณต๊ฐœ/๋น„๊ณต๊ฐœ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ช…๋จ
    • ์ด ํ† ํฐ๋“ค์€ ํ•œ์ชฝ ๋‹น์‚ฌ์ž์˜ ๋น„๊ณต๊ฐœ ํ‚ค(์ผ๋ฐ˜์ ์œผ๋กœ ์„œ๋ฒ„์˜ ๋น„๊ณต๊ฐœ ํ‚ค)์— ์˜ํ•ด ์„œ๋ช…์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ด๋กœ์จ ํ•ด๋‹น ๋‹น์‚ฌ์ž๋Š” ์ตœ์ข…์ ์œผ๋กœ ํ† ํฐ์ด ์ ๋ฒ•ํ•œ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ

 

๊ธฐ๋ณธ์ ์ธ ์ธ์ฆ์„ ์ง„ํ–‰ํ•˜๋Š” ๊ตฌ์กฐ๋Š” Cookie ๋•Œ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์ง€๋งŒ,
๊ฐ•์กฐ๋˜๋Š” ์ ์€ JWT๋Š” ์„œ๋ช…๋œ ํ† ํฐ์ด๋ผ๋Š” ์ 

JWT์˜ ์‚ฌ์šฉ

 

  • ํšŒ์›์ธ์ฆ : JWT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํ”ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค
    • ์œ ์ €๊ฐ€ ๋กœ๊ทธ์ธ ํ•˜๋ฉด, ์„œ๋ฒ„๋Š” ์œ ์ €์˜ ์ •๋ณด์— ๊ธฐ๋ฐ˜ํ•œ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜์—ฌ ์œ ์ €์—๊ฒŒ ์ „๋‹ฌ
    • ๊ทธ ํ›„, ์œ ์ €๊ฐ€ ์š”์ฒญ์„ ํ•  ๋•Œ๋งˆ๋‹ค JWT๋ฅผ ํฌํ•จํ•˜์—ฌ ์ „๋‹ฌ
    • ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ์„œ ์š”์ฒญ์„ ๋ฐ›์„๋•Œ ๋งˆ๋‹ค, ํ•ด๋‹น ํ† ํฐ์ด ์œ ํšจํ•˜๊ณ  ์ธ์ฆ๋˜์–ด์žˆ๋Š”์ง€ ๊ฒ€์ฆ
    • ์œ ์ €๊ฐ€ ์š”์ฒญํ•œ ์ž‘์—…์— ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์ž‘์—…์„ ์ฒ˜๋ฆฌ
    • ์„œ๋ฒ„์ธก์—์„œ๋Š” ์œ ์ €์˜ ์„ธ์…˜์„ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง
    • (์ฆ‰, ์œ ์ €๊ฐ€ ๋กœ๊ทธ์ธ ๋˜์–ด์žˆ๋Š”์ง€ ์•ˆ๋˜์–ด์žˆ๋Š”์ง€๋Š” ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†๊ณ , ์œ ์ €๊ฐ€ ์š”์ฒญ ํ–ˆ์„๋•Œ๋งŒ ํ† ํฐ์„ ํ™•์ธํ•˜๋ฉด๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„ธ์…˜๊ด€๋ฆฌ๊ฐ€ ํ•„์š” ์—†์–ด ์„œ๋ฒ„์ž์›์„ ๋งŽ์ด ์•„๋‚„ ์ˆ˜ ์žˆ์Œ)
  • ์ •๋ณด ๊ต๋ฅ˜ : JWT๋Š” ๋‘ ๊ฐœ์ฒด ์‚ฌ์ด์—์„œ ์•ˆ์ •์„ฑ ์žˆ๊ฒŒ ์ •๋ณด๋ฅผ ๊ตํ™˜ํ•˜๊ธฐ์— ์ข‹์€ ๋ฐฉ๋ฒ•
    • ๊ทธ ์ด์œ ๋Š” ์ •๋ณด๊ฐ€ sign์ด ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ •๋ณด๋ฅผ ๋ณด๋‚ธ์ด๊ฐ€ ๋ฐ”๋€Œ์ง„ ์•Š์•˜๋Š”์ง€, ๋˜ ์ •๋ณด๊ฐ€ ๋„์ค‘์— ์กฐ์ž‘๋˜์ง€๋Š” ์•Š์•˜๋Š”์ง€ ๊ฒ€์ฆ ๊ฐ€๋Šฅ

JWT์˜ ๊ตฌ์กฐ

https://jwt.io/ ์˜ JWT ์˜ˆ์‹œ

 

JWT๋Š” Header . PayLoad . Signature์˜ ์„ธ ๋ฉ์–ด๋ฆฌ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ, ๊ฐ ๋ถ€๋ถ„์€ ์ (.)์œผ๋กœ ์—ฐ๊ฒฐ

ํ•˜๋‹จ์˜ ํ…์ŠคํŠธ๊ฐ€ ํŒŒ๋ž€์ƒ‰์œผ๋กœ Signature Verified ๋ผ๊ณ  ๋œจ๋ฉด JWT ํ† ํฐ์ด ๊ฒ€์ฆ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ !

 

ํ—ค๋”(header)

์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ˜•์‹์„ ๊ธฐ์ˆ ํ•˜๋Š” ๋ถ€๋ถ„

{
 "alg" : "HS256",
 "typ" : "JWT"
}
  • alg : ํ•ด์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ง€์ •(์„œ๋ช… ์ƒ์„ฑ์„ ์œ„ํ•ด ์–ด๋Š ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ• ์ง€๋ฅผ ์‹๋ณ„)
    • HS256๋Š” ์ด ํ† ํฐ์ด  HMAC-SHA256๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ช…๋จ์„ ์˜๋ฏธ
    • ์ผ๋ฐ˜์ ์œผ๋กœ ๋งŽ์ด ์“ฐ์ด๋Š” ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • SHA-2(HS256) ๋ฐฉ์‹์˜ HMAC์™€ SHA-256(RS256) ๋ฐฉ์‹์˜ RSA ์„œ๋ช…
    • (์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ† ํฐ์„ ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” signature ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉ๋จ)

(์„ ํƒ ๊ฐ€๋Šฅ ์•Œ๊ณ ๋ฆฌ์ฆ˜)

  • typ : ํ† ํฐ์˜ ํƒ€์ž…์„ ์ง€์ • - JWT
์ฐธ๊ณ  : JSON ํ˜•ํƒœ์˜ ๊ฐ์ฒด๊ฐ€ base64๋กœ ์ธ์ฝ”๋”ฉ ๋˜๋Š” ๊ณผ์ •์—์„œ ๊ณต๋ฐฑ/์—”ํ„ฐ ๋“ค์€ ์‚ฌ๋ผ์ง
๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ž์—ด์„ ์ธ์ฝ”๋”ฉ ํ•˜๊ฒŒ ๋จ
{"alg":"HS256","typ":"JWT"}

ํŽ˜์ด๋กœ๋“œ(payload) - ์ •๋ณด

{
  "sub": "1234567890",
  "name": "admin",
  "iat": 1516239022
}
  • sub ํ† ํฐ์ œ๋ชฉ
  • name ์‚ฌ์šฉ์ž ์ง€์ • ํด๋ ˆ์ž„
  • iat ํ† ํฐ ๋ฐœ๊ธ‰์‹œ๊ฐ„
  • ํŽ˜์ด๋กœ๋“œ๋Š” ํ† ํฐ์— ๋‹ด์„ ์ •๋ณด๋กœ์„œ ํด๋ ˆ์ž„(claim) ํ‘œ๋ช…(assert)์„ ์ฒ˜๋ฆฌ ํ•˜๋Š” JSON์„ ๋ณด๊ด€ํ•˜๊ณ  ์žˆ์Œ
    • (ํŽ˜์ด๋กœ๋“œ. payload ๋Š” ์ „์†ก๋˜๋Š” '์ˆœ์ˆ˜ํ•œ ๋ฐ์ดํ„ฐ'๋ฅผ ์˜๋ฏธ)
    • ํด๋ ˆ์ž„(claim) : ๋‹ด๋Š” ์ •๋ณด์˜ ํ•œ '์กฐ๊ฐ'์„ ์˜๋ฏธ
    • name/value์˜ ํ•œ ์Œ์œผ๋กœ ๊ตฌ์„ฑ(key-value์˜ ํ˜•ํƒœ๋กœ ์ €์žฅ)
    • (ํ† ํฐ์—๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ํด๋ ˆ์ž„์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ)
  • ํด๋ ˆ์ž„์˜ ์ข…๋ฅ˜๋Š” ํฌ๊ฒŒ ์„ธ ๋ถ„๋ฅ˜๋กœ ๋‚˜๋ˆ„์–ด์ง
    • ๋“ฑ๋ก๋œ(registered) ํด๋ ˆ์ž„
    • ๊ณต๊ฐœ(public) ํด๋ ˆ์ž„
    • ๋น„๊ณต๊ฐœ(private) ํด๋ ˆ์ž„

๋“ฑ๋ก๋œ(registered) ํด๋ ˆ์ž„

 

์„œ๋น„์Šค์—์„œ ํ•„์š”ํ•œ ์ •๋ณด๋“ค์ด ์•„๋‹Œ, ํ† ํฐ์— ๋Œ€ํ•œ ์ •๋ณด๋“ค์„ ๋‹ด๊ธฐ ์œ„ํ•˜์—ฌ ์ด๋ฆ„์ด ์ด๋ฏธ ์ •ํ•ด์ง„ ํด๋ ˆ์ž„๋“ค

ํ‘œ์ค€ ์ŠคํŽ™์ƒ key์˜ ์ด๋ฆ„์€ 3๊ธ€์ž๋กœ ๋˜์–ด ์žˆ์Œ

(JWT์˜ ํ•ต์‹ฌ ๋ชฉํ‘œ๋Š” ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ, ํ† ํฐ์— ๋Œ€ํ•œ ํ‘œํ˜„์„ ์••์ถ•ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ)

ํ† ํฐ์— ์ผ๋ฐ˜์ ์œผ๋กœ ํฌํ•จ๋˜๋Š” ํ‘œ์ค€ ํ•„๋“œ์ธ 7๊ฐœ์˜ ๋“ฑ๋ก ํด๋ ˆ์ž„ ์ด๋ฆ„(Registered Claim Names)์„ ์ •์˜

  1. iss (Issuer) : ํ† ํฐ ๋ฐœ๊ธ‰์ž
  2. sub (Subject) : ํ† ํฐ ์ œ๋ชฉ - ํ† ํฐ์—์„œ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์‹๋ณ„ ๊ฐ’
  3. aud (Audience) : ํ† ํฐ ๋Œ€์ƒ์ž
  4. exp (Expiration Time) : ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ - ์‹œ๊ฐ„์€ NumericDate ํ˜•์‹
  5. nbf (Not Before) : ํ† ํฐ ํ™œ์„ฑ ๋‚ ์งœ (์ด ๋‚ ์งœ ์ด์ „์˜ ํ† ํฐ์€ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์Œ์„ ๋ณด์žฅ)
    • NumericDate ํ˜•์‹
    • ์ด ๋‚ ์งœ๊ฐ€ ์ง€๋‚˜๊ธฐ ์ „๊นŒ์ง€ ํ† ํฐ์ด ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์Œ
  6. iat (Issued At (Time)) : ํ† ํฐ ๋ฐœ๊ธ‰ ์‹œ๊ฐ„ - ์ด ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ํ† ํฐ์˜ 'age'๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋˜์—ˆ๋Š”์ง€ ํŒ๋‹จ ๊ฐ€๋Šฅ
  7. jti (JWT Id) : JWT ํ† ํฐ ์‹๋ณ„์ž (issuer๊ฐ€ ์—ฌ๋Ÿฌ ๋ช…์ผ ๋•Œ ์ด๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ’)
    • JWT์˜ ๊ณ ์œ  ์‹๋ณ„์ž
    • ์ฃผ๋กœ ์ค‘๋ณต์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์‚ฌ์šฉ
    • ์ผํšŒ์šฉ ํ† ํฐ์— ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉํ•จ

์ด๋Ÿฌํ•œ ํ‘œ์ค€ ์ŠคํŽ™์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ด์ง€, ๊ผญ ์ด 7๊ฐ€์ง€๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ (๋ชจ๋‘ ์„ ํƒ์  (optional)), ํ‘œ์ค€ ์ŠคํŽ™ ์™ธ์—๋„ ํ•„์š”ํ•˜๋‹ค ์‹ถ์œผ๋ฉด ์ถ”๊ฐ€ํ•ด๋„ ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์Œ (๊ฐœ๋ฐœ์ž์˜ ์ž์œ )


๊ณต๊ฐœ(public) ํด๋ ˆ์ž„

 

๊ณต๊ฐœ ํด๋ ˆ์ž„๋“ค์€ ์ถฉ๋Œ์ด ๋ฐฉ์ง€๋œ(collision-resistant)์ด๋ฆ„์„ ๊ฐ–๊ณ  ์žˆ์–ด์•ผ ํ•จ

์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํด๋ ˆ์ž„ ์ด๋ฆ„์„ URL ํ˜•์‹์œผ๋กœ ์ง€์Œ

{
    url : (bool type)
}

 

์ฃผ์˜: base64 ๋กœ ์ธ์ฝ”๋”ฉ์„ ํ•  ๋•Œ, ๋’ค์— = ๋ฌธ์ž๊ฐ€ ํ•œ๋‘๊ฐœ ๋ถ™์„ ๋•Œ๊ฐ€ ์žˆ์Œ.
์ด ๋ฌธ์ž๋Š” base64 ์ธ์ฝ”๋”ฉ์˜ padding ๋ฌธ์ž๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ,  URL ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ๋„ ์กด์žฌ
๋”ฐ๋ผ์„œ = ๋ฌธ์ž๋Š”, url-safe ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ œ๊ฑฐ๋˜์–ด์•ผ ํ•จ.
(ํŒจ๋”ฉ์ด ํ•œ๊ฐœ ์ƒ๊ธธ ๋•Œ๋„ ์žˆ๊ณ , ๋‘๊ฐœ ์ƒ๊ธธ ๋•Œ๋„ ์žˆ๋Š”๋ฐ, ์ „๋ถ€ ์ง€์›Œ๋„ (์ œ๊ฑฐํ•ด์ค˜๋„) ๋””์ฝ”๋”ฉ ํ•  ๋•Œ ์ „ํ˜€ ๋ฌธ์ œ X)

๋น„๊ณต๊ฐœ(private) ํด๋ ˆ์ž„

 

๋“ฑ๋ก๋œ ํด๋ ˆ์ž„๋„ ์•„๋‹ˆ๊ณ , ๊ณต๊ฐœ๋œ ํฌ๋ ˆ์ž„๋“ค๋„ ์•„๋‹Œ ๊ฒƒ

์–‘ ์ธก๊ฐ„์— (๋ณดํ†ต ํด๋ผ์ด์–ธํŠธ - ์„œ๋ฒ„) ํ•ฉ์˜ ํ•˜์— ์‚ฌ์šฉ๋˜๋Š” ํด๋ ˆ์ž„ ์ด๋ฆ„

(๊ณต๊ฐœ ํด๋ ˆ์ž„๊ณผ ๋‹ฌ๋ฆฌ ์ด๋ฆ„์ด ์ค‘๋ณต๋˜์–ด ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋‹ˆ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์˜ํ•ด์•ผ ํ•จ)

 

๋‹ค๋งŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ payload์— ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ๋‹ด์ง€ ์•Š๋Š” ๊ฒƒ

header์™€ payload๋Š” json์ด ๋””์ฝ”๋”ฉ๋˜์–ด์žˆ์„ ๋ฟ์ด์ง€ ํŠน๋ณ„ํ•œ ์•”ํ˜ธํ™”๊ฐ€ ๊ฑธ๋ ค์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๊ตฌ๋‚˜ jwt๋ฅผ ๊ฐ€์ง€๊ณ  ๋””์ฝ”๋”ฉ์„ ํ•œ๋‹ค๋ฉด ๋‹ด๊ฒจ์žˆ๋Š” ๊ฐ’์„ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ

๊ทธ๋Ÿฌ๋ฏ€๋กœ JWT์—๋Š” ๋‹จ์ˆœํžˆ "์‹๋ณ„์„ ํ•˜๊ธฐ ์œ„ํ•œ" ์ •๋ณด๋งŒ์„ ๋‹ด์•„๋‘์–ด์•ผ ํ•˜๋Š” ๊ฒƒ

์„œ๋ช…(signature)

ํ—ค๋”์˜ ์ธ์ฝ”๋”ฉ ๊ฐ’๊ณผ, ์ •๋ณด์˜ ์ธ์ฝ”๋”ฉ ๊ฐ’์„ ํ•ฉ์นœ ํ›„ ์ฃผ์–ด์ง„ ๋น„๋ฐ€ํ‚ค๋กœ ํ•ด์‹œ๋ฅผ ํ•˜์—ฌ ์ƒ์„ฑ

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
) //secret base64 encoded
  • ์œ„์˜ ๊ณผ์ •์œผ๋กœ ๋งŒ๋“  ํ•ด์‹œ๋ฅผ, base64 ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๋จ
  • (๋ฌธ์ž์—ด์„ ์ธ์ฝ”๋”ฉ ํ•˜๋Š”๊ฒŒ ์•„๋‹Œ hex → base64 ์ธ์ฝ”๋”ฉ์„ ํ•ด์•ผ ํ•จ)
  • ์•ž์—์„œ header ์™€ payload๋ฅผ ๋ณด์—ฌ์ค„ ๋•Œ๋Š” ์ธ์ฝ”๋”ฉ ๋˜์–ด ์žˆ๋˜ ๊ฐ’๋“ค์„ JWT์— ๋‹ด๊ฒจ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋””์ฝ”๋”ฉ๋œ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉ
  • heder๋ฅผ ๋””์ฝ”๋”ฉํ•œ ๊ฐ’, payload๋ฅผ ๋””์ฝ”๋”ฉํ•œ ๊ฐ’์„ ์œ„์ฒ˜๋Ÿผ ํ•ฉ์น˜๊ณ 
  • ์ด๋ฅผ your-256-bit-secret ์ฆ‰, ์„œ๋ฒ„๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐœ์ธํ‚ค๋ฅผ ๊ฐ€์ง€๊ณ  ์•”ํ˜ธํ™”๋˜์–ด์žˆ๋Š” ์ƒํƒœ
  • ๋”ฐ๋ผ์„œ signature๋Š” ์„œ๋ฒ„์— ์žˆ๋Š” ๊ฐœ์ธํ‚ค๋กœ๋งŒ ์•”ํ˜ธํ™”๋ฅผ ํ’€ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ๋Š” ์ž„์˜๋กœ ๋ณตํ˜ธํ™” ๋ถˆ๊ฐ€๋Šฅ
๋ณตํ˜ธํ™” ์ธ์ฆ ์ ˆ์ฐจ

1. JWT ํ† ํฐ์„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ ์š”์ฒญ๊ณผ ๋™์‹œ์— ์ „๋‹ฌ
2. ์„œ๋ฒ„๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐœ์ธํ‚ค๋ฅผ ๊ฐ€์ง€๊ณ  signature๋ฅผ ๋ณตํ˜ธํ™”
3. base64UrlEncode(header)๊ฐ€ JWT์˜ header ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ
4. base64UrlEncode(payload)์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ
5. ์ผ์น˜ํ•œ๋‹ค๋ฉด ์ธ์ฆ์„ ํ—ˆ์šฉ

 

๋งŒ์•ฝ ํด๋ผ์ด์–ธํŠธ๊ฐ€ payload์— ๋‹ด๊ธด ์‹๋ณ„์ž๊ฐ€ ๋ณ€์กฐ๋œ JWT๋กœ ์š”์ฒญํ•œ๋‹ค๋ฉด, ์„œ๋ฒ„๊ฐ€ ์• ์ดˆ์— ๋ฐœ๊ธ‰ํ–ˆ๋˜ signature ์•ˆ์˜ payload์™€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ฆ์ด ๋ถˆ๊ฐ€๋Šฅ

 

JWT์˜ ์žฅ์ 

  • ์ง€๊ธˆ๊นŒ์ง€ ์ฟ ํ‚ค์™€ ์„ธ์…˜์„ ๋„˜์–ด์˜ค๋ฉด์„œ ๊ฒช์—ˆ๋˜ ๋ชจ๋“  ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด JWT (๊ฐ๊ฐ์˜ ๋‹จ์ ์„ ๋’ค์ง‘์œผ๋ฉด ์žฅ์ )
  • ์ด๋ฏธ ํ† ํฐ ์ž์ฒด๊ฐ€ ์ธ์ฆ๋œ ์ •๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์„ธ์…˜ ์ €์žฅ์†Œ์™€ ๊ฐ™์€ ๋ณ„๋„์˜ ์ธ์ฆ ์ €์žฅ์†Œ๊ฐ€ 'ํ•„์ˆ˜์ '์œผ๋กœ ํ•„์š”ํ•˜์ง„ ์•Š์Œ
  • ์„ธ์…˜๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ํด๋ผ์ด์–ธํŠธ์˜ ์ƒํƒœ๋ฅผ ์„œ๋ฒ„๊ฐ€ ์ €์žฅํ•ด ๋‘์ง€ ์•Š์•„๋„ ๋จ
  • signature๋ฅผ ๊ณตํ†ตํ‚ค / ๊ฐœ์ธํ‚ค ์•”ํ˜ธํ™”๋ฅผ ํ†ตํ•ด ๋ง‰์•„๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ณด์™„์„ฑ์ด ๋†’์Œ
  • ๋‹ค๋ฅธ ์„œ๋น„์Šค์— ์ด์šฉ ๊ฐ€๋Šฅํ•œ ๊ณตํ†ต์ ์ธ ์ŠคํŽ™์œผ๋กœ์จ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

์ฆ‰, stateful ํ•ด์•ผ ํ•˜๋Š” ์„ธ์…˜์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ JWT๋Š” ๋ณ„๋„์˜ ์„ธ์…˜ ์ €์žฅ์†Œ๋ฅผ ๊ฐ•์ œํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— stateless(๋ฌด์ƒํƒœ์„ฑ์„ ์ถ”๊ตฌ)ํ•˜์—ฌ ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ , signature๋ฅผ ํ†ตํ•œ ๋ณด์™„์„ฑ๊นŒ์ง€ ๊ฐ–์ถค

 


JWT์˜ ์ทจ์•ฝ์„ฑ

JWT์˜ ์ทจ์•ฝ์„ฑ

JSON ์›น ํ† ํฐ์€ ์„ธ์…˜ ์ƒํƒœ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Œ
๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ์ ํŠธ ์š”๊ฑด์ด JWT ๊ธฐ๊ฐ„ ๋งŒ๋ฃŒ ์ด์ „์— ์„ธ์…˜ ๋ฌดํšจํ™”๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
-> ์„œ๋น„์Šค๋Š” ๋” ์ด์ƒ ํ† ํฐ๋งŒ์œผ๋กœ ํ† ํฐ ํ‘œ๋ช…(token assertion)์„ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๊ฒŒ ๋จ
    -> ํ† ํฐ์— ์ €์žฅ๋œ ์„ธ์…˜์ด ํ์ง€๋˜์ง€ ์•Š์Œ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ† ํฐ ํ‘œ๋ช…์€ ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด์— ๋Œ€ํ•ด ๊ฒ€์‚ฌ๋˜์–ด์•ผ ํ•จ
        -> ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ† ํฐ์ด ๋” ์ด์ƒ ๋ฌด์ƒํƒœ๊ฐ€ ์•„๋‹ˆ๊ฒŒ ๋จ์œผ๋กœ์จ JWT์˜ ์ฃผ๋œ ์ด์ ์ด ์•ฝํ™”๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ์Œ
  • ์ ์ ˆํžˆ ์„ค๊ณ„ํ•  ๊ฒฝ์šฐ ๊ฐœ๋ฐœ์ž๋Š” ์ผ๋ถ€ ์ฃผ์˜๋ฅผ ๊ธฐ์šธ์ด๋ฉด ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ทจ์•ฝ์„ฑ์„ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ
    • JWT ํ—ค๋”๋งŒ์œผ๋กœ ์œ ํšจ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์„ ๊ฒƒ
    • ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ธ์ง€ํ•  ๊ฒƒ
    • ์ ์ ˆํ•œ ํ‚ค ํฌ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ

์งง์€ JWT ์œ ํšจ์‹œ๊ฐ„์„ ๋ณด์™„ํ•˜๋Š” ๋ฐฉ๋ฒ•

 

JWT๊ฐ€ ๋งŒ๋ฃŒ๋˜๊ธฐ ์ง์ „์˜ ์œ ํšจ์‹œ๊ฐ„์„ ๋ณด๊ณ  ์žฌ๋ฐœ๊ธ‰ ๋ฐฉ์‹์„ ์–ด๋–ค์‹์œผ๋กœ ํ•˜๋Š๋ƒ?

 

  1. Sliding Session
    • ํŠน์ •ํ•œ ์„œ๋น„์Šค๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํŠน์ • ์œ ์ €์— ๋Œ€ํ•˜์—ฌ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ์—ฐ์žฅ์‹œ์ผœ์ฃผ๋Š” ๋ฐฉ๋ฒ•
    • ex) ์–ด๋–ค ๊ธ€์„ ์ง€์†์ ์œผ๋กœ ์“ฐ๊ณ  ์žˆ๋Š” ์œ ์ €๊ฐ€ ์งง์€ ๋งŒ๋ฃŒ์‹œ๊ฐ„ ๋•Œ๋ฌธ์— ๊ธ€์„ ์“ฐ๋‹ค๊ฐ€ ์ธ์ฆ ์ทจ์†Œ๋กœ ์ธํ•ด ์“ฐ๋˜ ๊ธ€์ด ๋‚ ์•„๊ฐ„๋‹ค๋ฉด?
    • Sliding Session์„ ์‚ฌ์šฉํ•˜๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • action์„ ์ทจํ–ˆ์„ ๋•Œ, ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋ฃŒ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚œ JWT๋ฅผ ๋‹ค์‹œ ์ œ๊ณตํ•จ์œผ๋กœ์จ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ์—ฐ์žฅํ•˜์—ฌ ๋ณด์™„ํ•˜๋Š” ๋ฐฉ๋ฒ•
    • ๋‹ค๋งŒ, ์ ‘์†์ด ๋‹จ๋ฐœ์„ฑ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด Sliding Session์œผ๋กœ ์—ฐ์žฅ์‹œ์ผœ์ค„ ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ์ƒ๊น€
    • ๋„ˆ๋ฌด ๊ธด JWT(Acess Token)์„ ๋ฐœ๊ธ‰์‹œ์ผœ์ค€ ์ƒํ™ฉ์ด๋ผ๋ฉด, Sliding Session์— ์˜ํ•ด ๋ฌดํ•œ์ • ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์ง€๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
  2. Refresh Token
    • ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•
    • JWT๋ฅผ ์ฒ˜์Œ ๋ฐœ๊ธ‰ํ•  ๋•Œ Acess Token๊ณผ  ํ•จ๊ป˜ Refresh Token์ด๋ผ๋Š” ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•˜์—ฌ ์งง์€ ๋งŒ๋ฃŒ์‹œ๊ฐ„์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•
    • ์งง์€ ์‹œ๊ฐ„์ด ์•„๋‹Œ ๋น„๊ต์  ๊ธด ์‹œ๊ฐ„์˜ ๋งŒ๋ฃŒ์‹œ๊ฐ„(7์ผ, 30์ผ etc.)์„ ๊ฐ€์ง„ Refresh Token์€ ๋ง ๊ทธ๋Œ€๋กœ Acess Token์„ Refresh ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜๋Š” ํ† ํฐ
      • 7์ผ, 30์ผ, 60์ผ, 90์ผ, ๋งŒ๋ฃŒ์—†์Œ(No Expiration), ์‚ฌ์šฉ์ž ์„ค์ •(Custom)
    • ๋งŒ์•ฝ ํด๋ผ์ด์–ธํŠธ๊ฐ€ Acess Token์ด ๋งŒ๋ฃŒ๋จ์„ ์ธ์ง€ํ•˜๊ฑฐ๋‚˜, ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋งŒ๋ฃŒ๋จ์„ ํ™•์ธ ๋ฐ›๋Š”๋‹ค๋ฉด Refresh Token์œผ๋กœ ์„œ๋ฒ„์—๊ฒŒ ์ƒˆ๋กœ์šด Acess Token์„ ๋ฐœ๊ธ‰ํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹
Refresh ๋™์ž‘ ๊ณผ์ •

1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ID, PW๋กœ ์„œ๋ฒ„์—๊ฒŒ ์ธ์ฆ์„ ์š”์ฒญ
2. ์„œ๋ฒ„๋Š” ์ด๋ฅผ ํ™•์ธํ•˜์—ฌ Access Token๊ณผ Refresh Token์„ ๋ฐœ๊ธ‰
3. ํด๋ผ์ด์–ธํŠธ๋Š” ์ด๋ฅผ ๋ฐ›์•„ Refresh Token์„ ๋ณธ์ธ์ด ์ž˜ ์ €์žฅํ•˜๊ณ , Access Token์„ ๊ฐ€์ง€๊ณ  ์„œ๋ฒ„์— ์ž์œ ๋กญ๊ฒŒ ์š”์ฒญ
4. ์š”์ฒญ ๋„์ค‘ Access Token์ด ๋งŒ๋ฃŒ๋˜์–ด ๋” ์ด์ƒ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์˜ค๋ฅ˜๋ฅผ ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ์ „๋‹ฌ ๋ฐ›์Œ
5. ํด๋ผ์ด์–ธํŠธ๋Š” ๋ณธ์ธ์ด ์‚ฌ์šฉํ•˜๋˜ Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ์Œ์„ ์ธ์ง€
6. ๋ณธ์ธ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋˜ Refresh Token์„ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜์—ฌ ์ƒˆ๋กœ์šด Access Token ๋ฐœ๊ธ‰์„ ์š”์ฒญ
7. ์„œ๋ฒ„๋Š” Refresh Token์„ ๋ฐ›์•„ ์„œ๋ฒ„์˜ Refresh Token Storage์— ํ•ด๋‹น ํ† ํฐ์ด ์žˆ๋Š”์ง€ ํ™•์ธ
8. ํ•ด๋‹น ํ† ํฐ์ด ํ™•์ธ๋˜๋ฉด Access Token์„ ์ƒ์„ฑํ•˜์—ฌ ์ „๋‹ฌ
9. (2)๋กœ ๋Œ์•„๊ฐ€์„œ ๊ณ„์†ํ•ด์„œ ๋™์ผํ•œ ์ž‘์—… ์ง„ํ–‰

 

  •  Refresh Token Storage ๋Š” ์„œ๋ฒ„์—์„œ Refresh Token์„ ์ €์žฅํ•˜๋Š” ์ €์žฅ์†Œ
  • ์–ด๋–ป๊ฒŒ ๋ณด๋ฉด ์„ธ์…˜ ์ €์žฅ์†Œ์™€ ๊ฐ™์€ ์—ญํ• ์„ ์ˆ˜ํ–‰
  • ๋งŒ๋ฃŒ๋œ Access Token์ด ๋” ์ด์ƒ ์ธ์ฆ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•˜๋ฏ€๋กœ, Refresh Token์„ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๊ณ , ์ด Refresh Token์ด ์„œ๋ฒ„์˜ Token ์ €์žฅ์†Œ์— ์žˆ๋Š”์ง€ ํ™•์ธ ํ›„ Access Token์„ ๋ฐœ๊ธ‰ํ•˜๋Š” ํ˜•ํƒœ
  • ์‚ฌ์‹ค์ƒ ์„ธ์…˜๊ณผ ๋ณ„๋ฐ˜ ์ฐจ์ด ์—†์ด ์ €์žฅ์†Œ(Storage)์— I/O ์ž‘์—…์ด ๋ฐœ์ƒํ•˜๋Š” ๊ผด
    • Access Token์ด ์ง€์†๋˜๋Š” ์งง์€ ์‹œ๊ฐ„๋™์•ˆ ์ด์™ธ์— ๊ฐฑ์‹ ์‹œ ๋งˆ๋‹ค
    • ๊ฒฐ๊ตญ ์„ธ์…˜๊ณผ ๋˜‘๊ฐ™์€ ๋‹จ์  ํ•˜๋‚˜๊ฐ€ ์ƒ๊ธฐ๊ฒŒ๋˜๋Š” ์…ˆ
      • ๋ฌผ๋ก  ์„ธ์…˜์˜ ๊ฒฝ์šฐ ์ธ์ฆ์„ ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค I/O
      • ํ•˜์ง€๋งŒ Refresh Token์˜ ๊ฒฝ์šฐ, Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ๋งŒ
      • ์ฃผ๊ธฐ๊ฐ€ ๋‹ค๋ฅด๊ธดํ•˜์ง€๋งŒ I/O๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์‚ฌ์‹ค๋งŒ ๊ฐ™์Œ
    • ๋‹ค๋งŒ ์„ธ์…˜์ฒ˜๋Ÿผ ํ† ํฐ ์ž์ฒด๊ฐ€ ํƒˆ์ทจ๋˜์—ˆ๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด, Refresh Token Storage๋ฅผ ์ดˆ๊ธฐํ™”ํ•จ์œผ๋กœ์จ ํƒˆ์ทจ๋œ ํ† ํฐ์ด ๋”์ด์ƒ Refresh ๋˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅ

JWT๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ์œ ์ง€

 

๋ชจ์˜ ํ•ดํ‚น ์Šคํ„ฐ๋”” - 3์ฃผ์ฐจ ๊ณผ์ œ (3-2) JWT ๊ตฌํ˜„(๋กœ๊ทธ์ธ ์œ ์ง€)


Reference

 

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

 

 

์งˆ๋ฌธ ํ™˜์˜, ์ˆ˜์ • ๋ฐ ๋ณด์™„์— ๋Œ€ํ•œ ์ง€์  ํ™˜์˜