A JSON Web Token consists of three parts: a header, a payload, and a signature.
When a user logs in, the server generates a JWT and sends it to the client. The client then includes this JWT in the Authorization
header of subsequent requests. The server verifies the JWT on each request to authenticate the user.
First, make sure you have Python installed. Then, create a virtual environment and install FastAPI and related libraries:
python -m venv venv
source venv/bin/activate # On Windows, use `venv\Scripts\activate`
pip install fastapi uvicorn python-jose[cryptography] passlib[bcrypt]
Here is a basic FastAPI application structure:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
To run the application, use the following command:
uvicorn main:app --reload
We will use the python-jose
library to generate and verify JWTs. Here is an example of generating a JWT:
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from passlib.context import CryptContext
# Secret key for signing the JWT
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def verify_token(token: str):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except JWTError:
return None
We can create a dependency function to verify the JWT on each request. Here is an example:
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def get_current_user(token: str = Depends(oauth2_scheme)):
payload = verify_token(token)
if not payload:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
return payload
@app.get("/protected")
def protected_route(user: dict = Depends(get_current_user)):
return {"message": "This is a protected route", "user": user}
JWTs are a powerful tool for securing FastAPI applications. By understanding the fundamental concepts, usage methods, and best practices, you can effectively implement authentication and authorization in your APIs. Remember to always follow security best practices to protect your application from potential threats.