๊ด€๋ฆฌ ๋ฉ”๋‰ด

<Hello Hosung๐Ÿ˜Ž/>

[CS ์ง€์‹] JWT(Json Web Token) ์ด๋ž€ ๋ณธ๋ฌธ

๐Ÿ“– CS Information

[CS ์ง€์‹] JWT(Json Web Token) ์ด๋ž€

์ขŒ์ถฉ์šฐ๋Œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ผ๊ธฐ๐Ÿง 2024. 11. 16. 23:55

1. JWT๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

JWT๋Š” JSON Web Token์˜ ์•ฝ์ž๋กœ, ์‚ฌ์šฉ์ž์˜ ์ธ์ฆ ์ •๋ณด์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ ์ธ์ฆ ํ† ํฐ์ž…๋‹ˆ๋‹ค. JWT๋Š” ์„ธ ๊ฐ€์ง€ ์ฃผ์š” ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค:

  • ํ—ค๋”(Header): ํ† ํฐ์˜ ํƒ€์ž…๊ณผ ์‚ฌ์šฉ๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ํŽ˜์ด๋กœ๋“œ(Payload): ์ธ์ฆ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ์œผ๋ฉฐ, ์ด ๋ฐ์ดํ„ฐ๋Š” ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„์— ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„œ๋ช…(Signature): ํ† ํฐ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์•”ํ˜ธํ™”๋œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

JWT๋Š” ์„ธ ๋ถ€๋ถ„์ด .(์ )์œผ๋กœ ๊ตฌ๋ถ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค: header.payload.signature.

2. JWT์˜ ์ž‘๋™ ์›๋ฆฌ

JWT์˜ ์ž‘๋™ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  1. ๋กœ๊ทธ์ธ: ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์‹œ, ์„œ๋ฒ„๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ํ™•์ธํ•œ ํ›„ JWT๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ํ† ํฐ ๋ฐœ๊ธ‰: ์„œ๋ฒ„๋Š” ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด JWT๋ฅผ ๋ฐœ๊ธ‰ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ(๋ณดํ†ต ๋ธŒ๋ผ์šฐ์ €๋‚˜ ์•ฑ)๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  3. ํ† ํฐ ์ €์žฅ: ํด๋ผ์ด์–ธํŠธ๋Š” ๋ฐœ๊ธ‰๋ฐ›์€ JWT๋ฅผ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€๋‚˜ ์ฟ ํ‚ค์— ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  4. ์š”์ฒญ ์‹œ ํ† ํฐ ์ „์†ก: ์ดํ›„ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋งˆ๋‹ค JWT๋ฅผ Authorization ํ—ค๋”์— ๋‹ด์•„ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  5. ์„œ๋ฒ„์—์„œ ๊ฒ€์ฆ: ์„œ๋ฒ„๋Š” ๋ฐ›์€ JWT๋ฅผ ์„œ๋ช…๋œ ํ‚ค๋ฅผ ์ด์šฉํ•ด ๊ฒ€์ฆํ•˜๊ณ , ์œ ํšจํ•œ ํ† ํฐ์ด๋ฉด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

3. JWT์˜ ๊ตฌ์„ฑ

JWT๋Š” ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค:

1) Header (ํ—ค๋”)

ํ—ค๋”๋Š” ํ† ํฐ์˜ ํƒ€์ž…(๋ณดํ†ต JWT)๊ณผ ์„œ๋ช…์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, HS256(HMAC SHA-256) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

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

 

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

ํŽ˜์ด๋กœ๋“œ์—๋Š” ํด๋ ˆ์ž„(Claim)์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํด๋ ˆ์ž„์€ JWT ์•ˆ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋กœ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • ๋“ฑ๋ก๋œ ํด๋ ˆ์ž„(Registered Claims): iss (๋ฐœ๊ธ‰์ž), exp (๋งŒ๋ฃŒ์‹œ๊ฐ„) ๋“ฑ.
  • ๊ณต๊ฐœ ํด๋ ˆ์ž„(Public Claims): ์‚ฌ์šฉ์ž ์ •์˜ ๋ฐ์ดํ„ฐ.
  • ๋น„๊ณต๊ฐœ ํด๋ ˆ์ž„(Private Claims): ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„์—๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ.

์˜ˆ๋ฅผ ๋“ค์–ด:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

 

3) Signature (์„œ๋ช…)

์„œ๋ช…์€ ํ—ค๋”์™€ ํŽ˜์ด๋กœ๋“œ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ๋น„๋ฐ€ ํ‚ค๋กœ ์„œ๋ช…ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด JWT์˜ ๋ฌด๊ฒฐ์„ฑ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„œ๋ช… ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

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

 

4. JWT์˜ ์žฅ์ 

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

5. JWT ์‚ฌ์šฉ ์‚ฌ๋ก€

JWT๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ์— ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค:

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

6. JWT ์‚ฌ์šฉ ์‹œ ๊ณ ๋ คํ•ด์•ผ ํ•  ๋ณด์•ˆ ์ 

JWT๋Š” ๊ฐ•๋ ฅํ•œ ์ธ์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด์ง€๋งŒ, ์ž˜๋ชป๋œ ์‚ฌ์šฉ์€ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŒ์ž…๋‹ˆ๋‹ค:

  • ์„œ๋ช… ๋น„๋ฐ€ ํ‚ค ๊ด€๋ฆฌ: ๋น„๋ฐ€ ํ‚ค๋Š” ๋งค์šฐ ์ค‘์š”ํ•œ ๋ณด์•ˆ ์š”์†Œ์ด๋ฏ€๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๊ด€ํ•ด์•ผ ํ•˜๋ฉฐ, ์ฃผ๊ธฐ์ ์œผ๋กœ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  • ํ† ํฐ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ ์„ค์ •: JWT์— ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์„ค์ •ํ•˜์—ฌ ํ† ํฐ์ด ๋ฌดํ•œํžˆ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, expํด๋ ˆ์ž„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • HTTP Only ์ฟ ํ‚ค ์‚ฌ์šฉ: ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ JWT๋ฅผ ์ €์žฅํ•  ๋•Œ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€ ๋Œ€์‹  HTTP Only ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ณด์•ˆ์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • Refresh Token ์‚ฌ์šฉ: JWT๊ฐ€ ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ, ์ƒˆ๋กœ์šด JWT๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก Refresh Token์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ์ธ์ฆ์„ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.

7. JWT๋ฅผ Node.js์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ

Node.js์—์„œ JWT๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค. ๋จผ์ € jsonwebtoken ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

npm install jsonwebtoken

 

JWT ์ƒ์„ฑ

const jwt = require('jsonwebtoken');

// ์œ ์ € ์ •๋ณด์™€ ๋น„๋ฐ€ ํ‚ค๋ฅผ ์ด์šฉํ•ด JWT ์ƒ์„ฑ
const token = jwt.sign({ userId: '123456' }, 'your-secret-key', { expiresIn: '1h' });

console.log(token);

 

JWT ๊ฒ€์ฆ

const jwt = require('jsonwebtoken');

const token = 'JWT_TOKEN_HERE';

jwt.verify(token, 'your-secret-key', (err, decoded) => {
  if (err) {
    console.log('Token is invalid');
  } else {
    console.log('Decoded payload:', decoded);
  }
});

 

8. ๋งˆ๋ฌด๋ฆฌ

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

 


์ฐธ๊ณ  ์ž๋ฃŒ