JWT (JSON Web Token) 무상태 인증
세션 방식은 접속자가 10만 명이 되면 서버 메모리(장부)가 터진다는 치명적인 단점이 있습니다. 이를 극복하기 위해 나온 기술이 바로 토큰 기반 무상태(Stateless) 인증 기법입니다.
💡 핵심 비유: 신분증 (주민등록증)
경찰이 시민의 신원을 확인할 때마다 경찰청 서버(세션)에 일일이 조회하지 않듯, 위조 불가능한 홀로그램 서명이 들어간 신분증(JWT)을 시민(브라우저)이 스스로 들고 다니며 요청마다 보여주는 방식입니다.
🛡️ 세션 vs JWT 인증 비교
📋 JWT의 3가지 구성 요소
| 구분 |
역할 |
내용 예시 |
| Header (헤더) |
어떤 알고리즘으로 암호화했는지 명시 |
{ "alg": "HS256", "typ": "JWT" } |
| Payload (페이로드) |
유저 ID, 권한 등 전달할 실제 데이터 조각(Claim) |
{ "userId": 1, "role": "admin" } |
| Signature (서명) |
가장 중요한 부분! 서버의 비밀키로 생성한 위조 방지 도장 |
HMACSHA256(base64(Header) + base64(Payload), SECRET_KEY) |
JWT 무상태 인증 시뮬레이션
서버가 어떻게 세션 DB 없이도 서명(Signature)만으로 사용자를 식별하고, 클라이언트가 발급받은 JWT 토큰을 어떻게 보관하여 사용하는지 확인해 보세요.
jwt_server.js (서버 로직)
const express = require('express');
const jwt = require('jsonwebtoken'); // JWT 라이브러리 사용
const app = express();
const SECRET_KEY = "my_super_secret_key"; // 서버만 알고 있는 절대 비밀키
app.post('/login', (req, res) => {
const { id, pw } = req.body;
if (id === 'admin' && pw === '1234') {
// 💥 [핵심] 서버 메모리나 DB에 아무것도 저장하지 않습니다!
// 오직 비밀키로 서명(Signature)을 하여 JWT 홀로그램 신분증을 만들어줍니다.
const token = jwt.sign(
{ userId: id, role: "admin" }, // Payload (유저 정보)
SECRET_KEY, // Signature 생성을 위한 비밀키
{ expiresIn: '1h' } // 토큰 유효기간
);
// 브라우저에게 토큰(문자열)을 그냥 전달합니다.
return res.json({ success: true, token });
}
res.status(401).json({ success: false, message: '인증 실패' });
});
app.get('/profile', (req, res) => {
// 클라이언트가 헤더에 담아 보낸 토큰 추출: "Bearer eyJhbG..."
const authHeader = req.headers.authorization;
if (!authHeader) return res.status(401).json({ message: '토큰 없음' });
const token = authHeader.split(' ')[1];
try {
// 💥 [핵심] DB 조회 없이 토큰 자체의 서명만 검사합니다!
const decoded = jwt.verify(token, SECRET_KEY);
// 서명이 일치하면 위조되지 않은 진짜 신분증입니다.
res.json({ authorized: true, user: decoded });
} catch(e) {
res.status(401).json({ authorized: false, message: '위조되거나 만료된 토큰' });
}
});
🎟️ JWT 무상태 인증 시뮬레이터
발급된 JWT 토큰 (Local Storage 보관)
Server Console
$ node jwt_server.js
서버 실행 중...