JWT, COOKIE, SESSION

์ด์Šน์ค€ยท2024๋…„ 2์›” 22์ผ
0

๐Ÿค”์ฟ ํ‚ค

์ฟ ํ‚ค

  • ํด๋ผ์ด์–ธํŠธ ์ธก(๋ธŒ๋ผ์šฐ์ €) ์— ์ €์žฅ๋˜๋Š” key-value ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ
  • response ๋กœ Cookie์— ์ €์žฅํ•˜๊ณ  request ํ—ค๋”๋ฅผ ํ†ตํ•ด Cookie๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ฟ ํ‚ค์—” key-value ๋ง๊ณ ๋„ ๋งŒ๋ฃŒ ๊ธฐ๊ฐ„, ๋„๋ฉ”์ธ, ๊ฒฝ๋กœ, HttpOnly, Secure ๋“ฑ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฟ ํ‚ค์˜ ํŠน์ง•

  • ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณ€๊ฒฝ, ์‚ญ์ œ, ์ถ”๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค
    => ๋ณด์•ˆ๋ฌธ์ œ๊ฐ€ ๋†’๋‹ค.

์ฟ ํ‚ค์˜ ์˜ต์…˜

Expires: ์ฟ ํ‚ค๊ฐ€ ๋งŒ๋ฃŒ๋˜๋Š” ๋‚ ์งœ
maxAge: ์ฟ ํ‚ค๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ๊นŒ์ง€ ๋‚จ์€ ๊ธฐ๊ฐ„(์ดˆ)
Domain: ์ฟ ํ‚ค๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋„๋ฉ”์ธ
Path: ํŠน์ • ๊ฒฝ๋กœ์— ์ ‘๊ทผ ์‹œ ์ฟ ํ‚ค ์ „์†ก
Secure: https ํ†ต์‹ ์—์„œ๋งŒ ์ฟ ํ‚ค ์ „์†ก
HttpOnly: ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์ฟ ํ‚ค ์ ‘๊ทผ ๋ฐฉ์ง€

  • maxAge์™€ expires์˜ ์ฐจ์ด์ ?? maxAge๋Š” ์ดˆ๋‹จ์œ„ expires๋Š” ๋‚ ์งœ๋‹จ์œ„

cookie-parser์—๋„ signed์˜ต์…˜์ด ์กด์žฌํ•ด ์ฟ ํ‚ค์˜ value ๋ณ€ํ˜•์—ฌ๋ถ€,
๋น„๋ฐ€ํ‚ค ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
ํ•˜์ง€๋งŒ ๋ณ€์กฐ๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ์กฐํšŒ๋ฅผ ๊ฐ์ง€ํ•˜์ง„ ๋ชปํ•œ๋‹ค.

๊ฒฐ๋ก 

์ฟ ํ‚ค๋ฅผ ์žฅ์ ์€ ์„œ๋ฒ„์— ๋ถ€ํ•˜๊ฐ€ ์ค„์–ด๋“ ๋‹ค.
๋™์‹œ์— ๋ธŒ๋ผ์šฐ์ €์— ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ์— ์ทจ์•ฝํ•˜๋‹ค.
์ฟ ํ‚ค๋งŒ์œผ๋กœ๋„ ๋ณด์•ˆ์„ฑ ์ทจ์•ฝ์ ์„ ์žก์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค.

๐Ÿค”์„ธ์…˜

์„ธ์…˜

์„ธ์…˜(session)์€ ์„œ๋ฒ„์— ์ €์žฅ๋˜๋Š” key-value ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ.

์„ธ์…˜์˜ ํŠน์ง•

์„œ๋ฒ„์— ์ €์žฅ๋œ ๋ฐœ๊ธ‰๋ฒˆํ˜ธ๋ฅผ ํ†ตํ•œ ์œ ์ €๋ฅผ ๊ฒ€์ฆํ•œ๋‹ค.
์ฆ‰ ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž์˜ ์ƒํƒœ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.
uuid์™€ ๊ฐ™์€๊ฒƒ์„ ์ƒ์„ฑ๋œ ์„ธ์…˜id๋Š” ์‚ฌ์šฉ์ž ์ธก์— ์ €์žฅํ•œ๋‹ค.

๐Ÿค”JWT

JWT

JsonWebToken์œผ๋กœ JSON ๊ฐ์ฒด๋ฅผ Base64 URL-safe Encode ๋กœ ์ธ์ฝ”๋”ฉํ•˜์—ฌ
๋น„๊ต์  ์•ˆ์ „ํ•˜๋‹ค.

JWT ๊ตฌ์กฐ

header.payload.signature ๋กœ ๊ตฌ๋ถ„๋œ๋‹ค.

  • ํ—ค๋”: ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ํƒ€์ž…์ด ๋“ค์–ด๊ฐ„๋‹ค.
  • ํŽ˜์ด๋กœ๋“œ: ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ„๋‹ค ์ด ๋•Œ ๋ฏธ๋ฆฌ์ •์˜๋œ ํด๋ ˆ์ž„์ค‘
    jti, iat, exp, sub, iss ๋“ฑ์€ ๊ธฐ์–ตํ•˜๊ณ  ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ์‹œ๊ทธ๋‹ˆ์ฒ˜: ์„œ๋ฒ„์—์„œ ์ •ํ•œ ๋น„๋ฐ€ํ‚ค๊ฐ€ ๋“ค์–ด์žˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ ์œ„๋ณ€์กฐ๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

๊ฒฐ๋ก 

๋ฆฌํ”„๋ž˜์‹œ ํ† ํฐ๊ณผ ํ•จ๊ป˜ ์šด์šฉํ•˜๋ฉด ์„ธ์…˜๋ฐฉ์‹๊ณผ ๋น„์Šทํ•˜๋‹ค.
ํ•˜์ง€๋งŒ ์„ธ์…˜๋ณด๋‹ค ์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์–‘์ด ์ ๋‹ค.

ํ—ค๋” ํŽ˜์ด๋กœ๋“œ๋Š” ๋””์ฝ”๋”ฉํ•˜๊ธฐ ๋งค์šฐ ํŽธ๋ฆฌํ•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ฟ ํ‚ค์™€ ๊ฐ™์ด
๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋„ฃ์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

๐Ÿค”๊ถ๊ธˆ์ฆ

์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์„œ๋น„์Šค๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์ด์œ 

  • ๊ฐ€๋Šฅํ•˜๋ฉด ์„œ๋น„์Šค ๋กœ์ง์ด req, res ๊ฐ์ฒด์— ์ ‘๊ทผ์„ ์•ˆํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
    • req, res ๋ชจํ‚น๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—
  • ๊ฐ€๋…์„ฑ, ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ์„ ์œ„ํ•ด ์“ด๋‹ค.
  • nestjs์˜ ๊ตฌ์กฐ๊ฐ•์ œ์„ฑ์ด ํ˜‘๋ ฅ ์‹œ ๋„์›€์ด ๋œ๋‹ค.
    • express๋Š” ๊ฐ„๋‹จํ•˜์ง€๋งŒ ์ž์œ ๋กœ์›Œ ํ˜‘๋ ฅ ์‹œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.

๋ฏธ๋“ค์›จ์–ด์˜ res ๊ฐ์ฒด

  • middleware์—์„œ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด http์š”์ฒญ ์‚ฌ์ดํด์ด ๋๋‚œ ํ›„
    response์— ์ ‘๊ทผ response ์กฐ์ž‘๋“ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค

  • ๋ฉ”์„œ๋“œ ์ข…๋ฅ˜

    • response.status() : Http ์‘๋‹ต์˜ ์ƒํƒœ์ฝ”๋“œ๋ฅผ ์„ค์ •
    • response.send(body) : ์‘๋‹ต(body)๋กœ ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ „์†ก
    • response.json({json}) : json ํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ์ „์†ก
    • response.redirect('/') : ํ•ด๋‹น url๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
    • response.setHeader(name,value) : ํ—ค๋” ์„ค์ •
    • response.cookie(name,value) : ์ฟ ํ‚ค ์„ค์ •
  • ์ด ๋•Œ json, redirect, send ๋“ฑ์€ next()๋ฅผ ์จ์ฃผ์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
    next()๋ฅผ ์จ์ฃผ๊ฒŒ ๋˜๋ฉด ์‘๋‹ต์ด ๋ณต์ˆ˜๋กœ ์ „๋‹ฌ๋˜์–ด ์˜ค๋ฅ˜๋ฐœ์ƒ๊ฐ€๋Šฅ์„ฑ์ด ์ƒ๊ธด๋‹ค.

Reference

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