JWT(JSON Web Token, RFC 7519)는 클레임(claim)들을 담은 JSON을 서명한 자기 완결적(self-contained) 토큰으로, `header.payload.signature` 세 부분을 각각 Base64URL로 인코딩해 점으로 잇습니다. 서버가 세션 저장소를 조회하지 않고도 서명만 검증하면 토큰 내용을 신뢰할 수 있어, 무상태(stateless) 인증의 사실상 표준입니다.
Usually Authorization: Bearer <header>.<payload>.<signature>header는 서명 알고리즘(alg)과 타입을, payload는 클레임을 담습니다. 표준 클레임으로 iss(발급자), sub(주체), aud(대상), exp(만료), nbf(유효 시작), iat(발급 시각), jti(토큰 ID)가 있습니다. signature는 header와 payload를 대칭키(HS256, 비밀 공유) 또는 비대칭키(RS256/ES256, 개인키 서명·공개키 검증)로 서명한 값입니다. 중요한 점은 payload가 암호화가 아니라 서명만 된다는 것입니다. 즉 내용은 누구나 디코드해 읽을 수 있으므로 비밀번호·개인정보를 넣으면 안 됩니다.
검증 시에는 서명 확인에 더해 exp(만료), aud(내가 대상이 맞는가), iss(신뢰하는 발급자인가)를 반드시 확인합니다. 이 세 클레임을 검증하지 않으면 만료된 토큰이나 다른 서비스용 토큰을 그대로 받아들이게 됩니다.
무상태의 대가는 폐기(revocation)의 어려움입니다. 서명이 유효하고 exp 이전이면 서버는 그 토큰을 계속 신뢰하므로, 강제 로그아웃·계정 정지를 즉시 반영하기 어렵습니다. 그래서 access token 수명을 짧게 두고, 필요하면 jti 블랙리스트나 토큰 버전 필드를 서버에 두어 반쯤 상태 있는 폐기 전략을 씁니다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaXNzIjoiZXhhbXBsZS5jb20iLCJhdWQiOiJhcGkiLCJleHAiOjE3MzUwMDAwMDB9.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8Ucurl -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiI...' https://api.example.com/meconst jwt = require('jsonwebtoken');
try {
const claims = jwt.verify(token, PUBLIC_KEY, {
algorithms: ['RS256'], // never allow 'none'
issuer: 'example.com',
audience: 'api'
});
} catch (e) { res.status(401).end(); }import jwt
claims = jwt.decode(
token, PUBLIC_KEY,
algorithms=['RS256'], # pin the algorithm
issuer='example.com', audience='api',
options={'require': ['exp', 'iss', 'aud']}
)