๐Ÿช™ ํ† ํฐ

์€์œ ๋กœ๊ทธยท2021๋…„ 10์›” 25์ผ
0

๐Ÿ“š study

๋ชฉ๋ก ๋ณด๊ธฐ
14/21

ํ† ํฐ(Token)

ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

์„ธ์…˜๊ธฐ๋ฐ˜ ์ธ์ฆ์—์„  ์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„๋Š” ๋งค๋ฒˆ DB์—์„œ ํ™•์ธํ•œ๋‹ค. ์ด ๋ถ€๋‹ด์„ ๋œ์–ด๋‚ด๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆํ•œ ๋ฐฉ๋ฒ•์ด ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์ด๋‹ค.
๋Œ€ํ‘œ์ ์ธ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์€ JWT(Json Web Token)์ด ์žˆ๋‹ค.

ํ† ํฐ?

์šฐ๋ฆฌ ์ผ์ƒ์ƒํ™œ์—์„œ ์•„๋Š” ํ† ํฐ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • ์˜ค๋ฝ์‹ค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ
  • ํ–‰์‚ฌ์— ์ž…์žฅํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ
  • ๋†€์ด๊ณต์›์— ์ž…์žฅ๋ฃŒ๋ฅผ ๋‚ด๋ฉด ์ฃผ๋Š” ํ† ํฐ

์ฆ‰, ๊ฐ ์‹œ์„ค์— ๋งž๋Š” ํ† ํฐ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ํ•ด๋‹น ์‹œ์„ค์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์€ ํด๋ผ์ด์–ธํŠธ์— ์ธ์ฆ ์ •๋ณด๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๊ณ ์•ˆ๋˜์—ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์—๊ฒŒ ํ† ํฐ์„ ๋ณด์—ฌ์ฃผ๊ณ  ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค.
์ค‘์š”ํ•œ ๊ฑด ํด๋ผ์ด์–ธํŠธ์— ํ† ํฐ์„ ๊ทธ๋Œ€๋กœ ๋‹ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์•”ํ˜ธํ™”ํ•œ ํ† ํฐ์„ ๋‹ด์•„์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์˜ ์žฅ์ 

  1. Statelessness & Scalability (๋ฌด์ƒํƒœ์„ฑ & ํ™•์žฅ์„ฑ)
    • ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ํ•„์š” ์—†๊ณ  ํ† ํฐ ํ•ด๋…์ด ๋˜๋Š”์ง€๋งŒ ํŒ๋‹จํ•œ๋‹ค.
    • ํด๋ผ์ด์–ธํŠธ๋Š” ์ƒˆ๋กœ์šด ์š”์ฒญ์„ ๋ณด๋‚ผ๋•Œ๋งˆ๋‹ค ํ† ํฐ์„ ํ—ค๋”์— ํฌํ•จ์‹œํ‚ค๋ฉด ๋œ๋‹ค.
    • ๊ฐ™์€ ํ† ํฐ์œผ๋กœ ์—ฌ๋Ÿฌ ์„œ๋ฒ„์—์„œ ์ธ์ฆ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์„œ๋น„์Šค๋ผ๋ฉด ๋”์šฑ ๋„์›€์ด ๋œ๋‹ค.
  2. ์•ˆ์ „ํ•˜๋‹ค.
    • ์•”ํ˜ธํ™” ํ•œ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๊ณ , ์•”ํ˜ธํ™” ํ‚ค๋ฅผ ๋…ธ์ถœ ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ „ํ•˜๋‹ค.
  3. ์–ด๋””์„œ๋‚˜ ์ƒ์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ํ† ํฐ์„ ํ™•์ธํ•˜๋Š” ์„œ๋ฒ„๊ฐ€ ํ† ํฐ์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ๋ฒ•์€ ์—†๋‹ค.
    • ํ† ํฐ ์ƒ์„ฑ์šฉ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ํšŒ์‚ฌ์—์„œ ํ† ํฐ๊ด€๋ จ ์ž‘์—…์„ ๋งก๊ธฐ๋Š” ๊ฒƒ ๋“ฑ ๋‹ค์–‘ํ•œ ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  4. ๊ถŒํ•œ ๋ถ€์—ฌ์— ์šฉ์ดํ•˜๋‹ค.
    • ํ† ํฐ์˜ payload ์•ˆ์— ์–ด๋–ค ์ •๋ณด์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ์ง€ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
      ex) ์„œ๋น„์Šค์˜ ์‚ฌ์ง„๊ณผ ์—ฐ๋ฝ์ฒ˜ ์‚ฌ์šฉ๊ถŒํ•œ๋งŒ ๋ถ€์—ฌ

JWT(Json Web Token)

๋Œ€ํ‘œ์ ์ธ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ ๊ธฐ์ˆ ์ด๋‹ค. Jsonํฌ๋งท์œผ๋กœ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ €์žฅํ•˜๋Š” ์›น ํ† ํฐ์ด๋‹ค. JWT๋Š” 2๊ฐœ์˜ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • Access Token
  • Refresh Token

Access Token

๋ณดํ˜ธ๋œ ์ •๋ณด๋“ค(์‚ฌ์šฉ์ž์˜ ์ด๋ฉ”์ผ, ์—ฐ๋ฝ์ฒ˜, ์‚ฌ์ง„ ๋“ฑ)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ๋ถ€์—ฌ์— ์‚ฌ์šฉํ•œ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฒ˜์Œ ์ธ์ฆ์„ ๋ฐ›๊ฒŒ ๋  ๋•Œ acess token, refresh token 2๊ฐœ๋ฅผ ๋‹ค ๋ฐ›์ง€๋งŒ ์‹ค์ œ๋กœ ๊ถŒํ•œ์„ ์–ป๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ์€ access token ์ด๋‹ค.

Refresh Token

๊ทธ๋ ‡๋‹ค๋ฉด access token๋งŒ ์žˆ์œผ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€?

๊ถŒํ•œ๋ถ€์—ฌ ๋ฐ›๋Š”๋ฐ๋Š” access token๋งŒ ์žˆ์œผ๋ฉด ๋˜์ง€๋งŒ, ๋งŒ์•ฝ access token์ด ๊ณต๊ฒฉ์ž๋กœ๋ถ€ํ„ฐ ํƒˆ์ทจ ๋‹นํ–ˆ๋‹ค๋ฉด ์ค‘์š” ์ •๋ณด๊ฐ€ ๊ณต๊ฒฉ์ž ์†์— ๋„˜์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.
๊ทธ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด access token์€ ์งง์€ ์œ ํšจ๊ธฐ๊ฐ„์„ ์„ค์ •ํ•˜๋Š”๋ฐ, ์ด๋•Œ ์œ ํšจ๊ธฐ๊ฐ„์ด ๋งŒ๋ฃŒ๋œ๋‹ค๋ฉด refresh token์„ ์‚ฌ์šฉํ•ด ์ƒˆ๋กœ์šด access token์„ ๋ฐœ๊ธ‰๋ฐ›๋Š”๋‹ค. ๊ทธ๋Ÿผ ์‚ฌ์šฉ์ž๋Š” ์žฌ๋กœ๊ทธ์ธํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

refresh token๋„ ํƒˆ์ทจ ๋‹นํ•œ๋‹ค๋ฉด?

๊ณต๊ฒฉ์ž๊ฐ€ access token์ด ๋งŒ๋ฃŒ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ๋ฐœ๊ธ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํฐ ๋ฌธ์ œ๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค. ์œ ์ €์˜ ํŽธ์˜๋ณด๋‹ค ์ •๋ณด๋ฅผ ์ง€ํ‚ค๋Š” ๊ฒƒ์ด ๋” ์ค‘์š”ํ•œ ์›น์‚ฌ์ดํŠธ๋“ค์€ refresh token์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ณณ์ด ๋งŽ๋‹ค. ๋”ฐ๋ผ์„œ Oauth, ์ฟ ํ‚ค, ์„ธ์…˜ ๋“ฑ๋“ฑ ๊ฐ ๋ฐฉ๋ฒ•๋“ค์˜ ์žฅ๋‹จ์ ์„ ์ฐธ๊ณ ํ•˜๋ฉฐ ํ•„์š”์— ๋งž๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

JWT์˜ ๊ตฌ์กฐ


JWT๋Š” . ์„ ๊ธฐ์ค€์œผ๋กœ ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

1. Header

ํ—ค๋”๋Š” ์ด๊ฒƒ์ด ์–ด๋–ค ์ข…๋ฅ˜์˜ ํ† ํฐ์ธ์ง€, ์–ด๋–ค ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ sign(์•”ํ˜ธํ™”) ํ• ์ง€๊ฐ€ ์ ํ˜€์žˆ๋‹ค.

{
  "alg": "HS256",
  "typ": "JWT"
}

์ด JSON ๊ฐ์ฒด๋ฅผ base64 ๋ฐฉ์‹์œผ๋กœ ์ธ์ฝ”๋”ฉํ•˜๋ฉด JWT์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์ด ์™„์„ฑ๋œ๋‹ค.

2. Payload

ํŽ˜์ด๋กœ๋“œ์—๋Š” ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ ์žˆ๋‹ค. ์–ด๋–ค ์ •๋ณด์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ์ง€์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ๋‹ด์„ ์ˆ˜๋„ ์žˆ๊ณ , ์‚ฌ์šฉ์ž์˜ ์œ ์ € ์ด๋ฆ„ ๋“ฑ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋Š” ์ด๊ณณ์— ๋‹ด์•„ ์•”ํ˜ธํ™” ์‹œํ‚จ๋‹ค. ๋ฌผ๋ก  ์•”ํ˜ธํ™”(ํ—ค๋”์—์„œ ์ •์˜ํ•œ)๊ฐ€ ๋  ์ •๋ณด์ง€๋งŒ, ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ๋˜๋„๋ก ๋‹ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

{
  "sub": "someInformation",
  "name": "phillip",
  "iat": 151623391
}

์ด JSON ๊ฐ์ฒด๋ฅผ base64๋กœ ์ธ์ฝ”๋”ฉํ•˜๋ฉด JWT์˜ ๋‘ ๋ฒˆ์งธ ๋ถ€๋ถ„์ด ์™„์„ฑ๋œ๋‹ค.

3. Signature

base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ์ฒซ๋ฒˆ์งธ, ๋‘๋ฒˆ์งธ ๋ถ€๋ถ„์ด ์™„์„ฑ ๋˜์—ˆ๋‹ค๋ฉด, ์›ํ•˜๋Š” ๋น„๋ฐ€ ํ‚ค(์•”ํ˜ธํ™”์— ์ถ”๊ฐ€ํ•  salt)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•”ํ˜ธํ™”ํ•œ๋‹ค. base64 ์ธ์ฝ”๋”ฉ์„ ํ•œ ๊ฐ’์€ ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ๋””์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋น„๋ฐ€ํ‚ค๋ฅผ ๋ณด์œ ํ•œ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด ์‰ฝ๊ฒŒ ํ•ด๋…ํ•˜์ง€ ๋ชปํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋งŒ์•ฝ HMAC SHA256 ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด signature๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

JWT ํ๋ฆ„

  1. ํด๋ผ์ด์–ธํŠธโžก๏ธ์„œ๋ฒ„ // ID, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ๋กœ๊ทธ์ธํ•œ๋‹ค. (POST ์š”์ฒญ)
  2. ์„œ๋ฒ„โžก๏ธ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค // ์š”์ฒญ๋ฐ›์€ ID, ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  3. ์„œ๋ฒ„ // ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ผ ์•”ํ˜ธํ™”๋œ ํ† ํฐ(access token, refresh token)์„ ์ƒ์„ฑํ•œ๋‹ค. ํ† ํฐ์— ๋‹ด๊ธธ ์ •๋ณด(payload)๋Š” ์œ ์ €๋ฅผ ์‹๋ณ„ํ•  ์ •๋ณด, ๊ถŒํ•œ์ด ๋ถ€์—ฌ๋œ ์นดํ…Œ๊ณ ๋ฆฌ(์‚ฌ์ง„, ์—ฐ๋ฝ์ฒ˜, ๊ธฐํƒ€๋“ฑ๋“ฑ)์ด ๋  ์ˆ˜ ์žˆ๊ณ , ๋‘ ์ข…๋ฅ˜์˜ ํ† ํฐ์ด ๊ฐ™์€ ์ •๋ณด๋ฅผ ๋‹ด์„ ํ•„์š”๋Š” ์—†๋‹ค.
  4. ์„œ๋ฒ„โžก๏ธํด๋ผ์ด์–ธํŠธ // ์ƒ์„ฑํ•œ ์•”ํ˜ธํ™”๋œ ํ† ํฐ์„ ๋ณด๋‚ธ๋‹ค. ์ด๋•Œ ํด๋ผ์ด์–ธํŠธ๋Š” ํ† ํฐ์„ local storage, cookie, react์˜ state ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ๊ณณ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
  5. ํด๋ผ์ด์–ธํŠธโžก๏ธ์„œ๋ฒ„ // ํ† ํฐ์„ HTTP ํ—ค๋”์— ๋‹ด์•„ ๋ณด๋‚ธ๋‹ค. (GET ์š”์ฒญ)
    ex) Headers: {Authorization: "Bearer JWT_TOKEN"}
  6. ์„œ๋ฒ„ // ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํ† ํฐ์„ ํ•ด๋…ํ•ด ์„œ๋ฒ„๊ฐ€ ๋ฐœ๊ธ‰ํ•œ ํ† ํฐ์ด ๋งž๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  7. ์„œ๋ฒ„โžก๏ธํด๋ผ์ด์–ธํŠธ // ์„œ๋ฒ„๊ฐ€ ๋ฐœ๊ธ‰ํ•œ ํ† ํฐ์ด ๋งž๋Š”์ง€ ํ™•์ธ๋๋‹ค๋ฉด ์›ํ•˜๋Š” ์š”์ฒญ ํ•ด๊ฒฐ & ์‘๋‹ต์„ ๋ณด๋‚ธ๋‹ค.
profile
เน‘โ€ขโ€ฟโ€ขเน‘

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