patternpythonfastapiMajor
FastAPI OAuth2 with JWT — password flow and token verification
Viewed 0 times
python-jose 3.x, passlib 1.7+
OAuth2JWTauthenticationbearer tokenjosepassword flow
Error Messages
Problem
Implementing token-based authentication from scratch is error-prone. Common mistakes include not validating token expiry, using weak secrets, or leaking token details in errors.
Solution
Use FastAPI's OAuth2PasswordBearer with python-jose for JWT. Centralize token creation and verification. Return 401 with WWW-Authenticate header for invalid tokens.
from datetime import datetime, timedelta
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from passlib.context import CryptContext
SECRET_KEY = 'your-secret-key-from-env'
ALGORITHM = 'HS256'
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=['bcrypt'])
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode['exp'] = expire
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
headers={'WWW-Authenticate': 'Bearer'},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username = payload.get('sub')
if username is None:
raise credentials_exception
except JWTError:
raise credentials_exception
return usernameWhy
OAuth2PasswordBearer tells FastAPI where to find the token and generates the correct OpenAPI security schema. JWT expiry (exp claim) is verified by jose automatically when decoding.
Gotchas
- Never hardcode SECRET_KEY — load from environment variable
- HS256 tokens are only signed, not encrypted — don't put sensitive data in the payload
- Token revocation requires a denylist (Redis) since JWTs are stateless
- Use refresh tokens for longer sessions instead of long-lived access tokens
- datetime.utcnow() is deprecated in Python 3.12 — use datetime.now(timezone.utc)
Context
FastAPI apps requiring user authentication with token-based auth
Revisions (0)
No revisions yet.