What is JWT (JSON Web Token)?
JWT (JSON Web Token) is a compact, URL-safe token format for securely transmitting claims between parties. It's widely used for API authentication and authorization in modern web applications.
// Table of Contents
Definition
A JSON Web Token (JWT) is an open standard (RFC 7519) for creating compact, self-contained tokens that securely represent claims between two parties. A JWT consists of three parts separated by dots: header.payload.signature.
JWTs are commonly used for authentication in REST APIs. After a user logs in, the server issues a JWT that the client includes in subsequent requests. The server can verify the token's authenticity without querying a database.
JWT Structure
- Header: Contains the token type (JWT) and signing algorithm (HS256, RS256).
- Payload: Contains claims - statements about the user and additional data (user ID, roles, expiration).
- Signature: Created by signing the encoded header and payload with a secret key. Ensures the token hasn't been tampered with.
The token is Base64URL-encoded, making it safe for URLs, HTTP headers, and cookies. The payload is not encrypted - anyone can read it. The signature only ensures integrity.
JWT Security Best Practices
- Keep tokens short-lived (15-60 minutes for access tokens)
- Use refresh tokens for long-lived sessions
- Never store sensitive data in the payload (it's readable by anyone)
- Use strong signing algorithms (RS256 over HS256 for distributed systems)
- Store tokens securely (httpOnly cookies over localStorage)
- Always validate expiration, issuer, and audience claims
- Implement token blacklisting for logout functionality
Code Example
from datetime import datetime, timedelta
from jose import jwt, JWTError
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer
SECRET_KEY = "your-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)
async def get_current_user(token: str = Depends(HTTPBearer())):
try:
payload = jwt.decode(token.credentials, SECRET_KEY, algorithms=[ALGORITHM])
return payload["sub"]
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
Frequently Asked Questions
Is JWT the same as OAuth?
No. JWT is a token format. OAuth is an authorization framework. OAuth can use JWTs as the token format, but they serve different purposes. OAuth defines the flow for obtaining tokens; JWT defines the structure of the token itself.
Should I store JWT in localStorage or cookies?
HttpOnly cookies are more secure because they can't be accessed by JavaScript, preventing XSS attacks from stealing tokens. localStorage is vulnerable to XSS but simpler to implement. For production APIs, prefer httpOnly cookies with SameSite and Secure flags.
Need expert backend development?
I build scalable Python APIs and backend systems. Let's discuss your project.
Get in Touch