How to Use JWT in FastAPI for Secure Authentication
Use the
pyjwt library to create and verify JSON Web Tokens (JWT) in FastAPI. Generate tokens on user login and protect routes by decoding and validating the token in a dependency.Syntax
This is the basic pattern to use JWT in FastAPI:
- Create a token: Use
jwt.encode()with a payload and secret key. - Decode a token: Use
jwt.decode()to verify the token and extract data. - Protect routes: Use FastAPI dependencies to check the token before allowing access.
python
from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer import jwt SECRET_KEY = "your-secret-key" ALGORITHM = "HS256" oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def create_access_token(data: dict): encoded_jwt = jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt def verify_token(token: str): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) return payload except jwt.PyJWTError: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token", headers={"WWW-Authenticate": "Bearer"}, )
Example
This example shows a FastAPI app that creates a JWT token on login and protects a route that requires a valid token.
python
from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm import jwt app = FastAPI() SECRET_KEY = "your-secret-key" ALGORITHM = "HS256" oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # Fake user data fake_user = {"username": "alice", "password": "wonderland"} def create_access_token(data: dict): return jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM) def verify_token(token: str = Depends(oauth2_scheme)): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username = payload.get("sub") if username is None: raise HTTPException(status_code=401, detail="Invalid token") return username except jwt.PyJWTError: raise HTTPException(status_code=401, detail="Invalid token") @app.post("/token") async def login(form_data: OAuth2PasswordRequestForm = Depends()): if form_data.username != fake_user["username"] or form_data.password != fake_user["password"]: raise HTTPException(status_code=400, detail="Incorrect username or password") access_token = create_access_token({"sub": form_data.username}) return {"access_token": access_token, "token_type": "bearer"} @app.get("/protected") async def protected_route(username: str = Depends(verify_token)): return {"message": f"Hello, {username}. You are authenticated."}
Output
POST /token with correct username/password returns {"access_token": "<jwt_token>", "token_type": "bearer"}
GET /protected with Authorization: Bearer <jwt_token> returns {"message": "Hello, alice. You are authenticated."}
Common Pitfalls
- Using a weak or hardcoded
SECRET_KEYcan compromise security. - Not setting the correct
algorithminjwt.encodeandjwt.decodecauses verification failures. - Failing to handle token expiration or errors properly leads to confusing responses.
- Not using FastAPI's
Dependsto enforce token verification on protected routes.
python
from fastapi import HTTPException import jwt # Wrong: No algorithm specified in decode try: jwt.decode(token, SECRET_KEY) except jwt.PyJWTError: raise HTTPException(status_code=401, detail="Invalid token") # Right: Specify algorithm jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
Quick Reference
| Step | Description | Code Snippet |
|---|---|---|
| 1 | Create JWT token with payload and secret | jwt.encode(data, SECRET_KEY, algorithm=ALGORITHM) |
| 2 | Decode and verify token | jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) |
| 3 | Use FastAPI dependency to get token | token: str = Depends(oauth2_scheme) |
| 4 | Raise HTTPException on invalid token | raise HTTPException(status_code=401, detail="Invalid token") |
| 5 | Protect routes by requiring verified token | @app.get('/protected')\nasync def route(user=Depends(verify_token)): |
Key Takeaways
Always use a strong SECRET_KEY and specify the algorithm when encoding and decoding JWTs.
Create tokens on login and verify them in dependencies to protect FastAPI routes.
Handle exceptions to return clear 401 Unauthorized responses for invalid tokens.
Use FastAPI's OAuth2PasswordBearer to extract tokens from requests easily.
Test your JWT flow by requesting tokens and accessing protected endpoints with them.