JWT(JSON Web Token)는 현대 API 인증의 표준으로 자리잡았습니다.
하지만 잘못 구현하면 세션 방식보다 훨씬 위험할 수 있습니다.
JWT의 구조
JWT는 점(.)으로 구분된 세 부분으로 이루어집니다.
- Header: 알고리즘 타입 (예: HS256, RS256)
- Payload: 사용자 정보, 만료 시간 등 클레임
- Signature: Header + Payload를 비밀키로 서명한 값
Base64 인코딩이지 암호화가 아니기 때문에 Payload는 누구나 디코딩해서 볼 수 있습니다.
민감 정보(비밀번호, 카드번호)를 절대 Payload에 담으면 안 됩니다.
JWT의 장점
- 무상태(Stateless): 서버가 세션을 저장하지 않아도 됩니다
- 확장성: 여러 서버에 걸쳐 인증이 가능 (MSA에 적합)
- 자기 완결성: 토큰 안에 필요한 정보가 다 포함됨
JWT의 위험성과 대응
1. 토큰 탈취
JWT는 탈취되면 만료 전까지 사용 가능합니다.
Refresh Token은 HTTP-only 쿠키로, Access Token은 메모리에만 저장하세요.
2. 알고리즘 혼동 공격
alg: none을 허용하면 서명 없이 모든 토큰이 유효해집니다.
반드시 허용 알고리즘 화이트리스트를 서버에서 강제하세요.
3. 긴 만료 시간
Access Token은 15분~1시간, Refresh Token은 7~30일로 설정합니다.
안전한 구현 패턴
import jwt
from datetime import datetime, timedelta
SECRET_KEY = "환경변수로 관리할 것"
ALGORITHM = "HS256"
def create_access_token(user_id: int) -> str:
payload = {
"sub": str(user_id),
"exp": datetime.utcnow() + timedelta(minutes=30),
"iat": datetime.utcnow(),
}
return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
JWT는 편리하지만, 올바르게 이해하고 구현했을 때만 안전합니다.
작성한 정보가 조금이나마 유익하고 도움이 되셨다면, 가시기 전에 아래 광고 한번 살짝 눌러주시면 정말 큰 힘이 됩니다. 감사합니다!