Learn / Frameworks / FastAPI / Dependency Injection and Auth

FastAPI · Lesson 4 of 5

Dependency Injection and Auth

Share logic with Depends, and protect routes with tokens.

  • Intermediate
  • 16 min read
  • 3 objectives

Before this lessonLesson 3: Models, Responses and Errors

What you will learn

  • Write a dependency
  • Inject a database session
  • Protect a route

Many endpoints need the same things: a database session, the current user, pagination settings. Dependency injection lets you declare what an endpoint needs, and FastAPI provides it. You write the shared logic once with Depends.

A simple dependency

from fastapi import Depends

def pagination(skip: int = 0, limit: int = 20):
    return {"skip": skip, "limit": min(limit, 100)}

@app.get("/items")
def list_items(page: dict = Depends(pagination)):
    return page

@app.get("/users")
def list_users(page: dict = Depends(pagination)):
    return page

Dependencies with cleanup

A dependency that uses yield runs setup before the endpoint and cleanup after it, perfect for database sessions.

from sqlalchemy.orm import Session
from .database import SessionLocal

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/posts")
def posts(db: Session = Depends(get_db)):
    return db.query(Post).all()

Authentication with a bearer token

FastAPI includes security helpers. The pattern: a dependency reads and verifies the token, and any route that lists it is protected.

from fastapi.security import OAuth2PasswordBearer
import jwt   # pip install pyjwt

oauth2 = OAuth2PasswordBearer(tokenUrl="login")
SECRET, ALGO = "change-me", "HS256"      # load from environment in real apps

def current_user(token: str = Depends(oauth2)):
    try:
        payload = jwt.decode(token, SECRET, algorithms=[ALGO])
    except jwt.PyJWTError:
        raise HTTPException(401, "Invalid token", headers={"WWW-Authenticate": "Bearer"})
    return payload["sub"]

@app.get("/me")
def me(user: str = Depends(current_user)):
    return {"user": user}

Issuing tokens on login uses jwt.encode({"sub": username, "exp": ...}, SECRET, algorithm=ALGO). Passwords must be stored hashed, for example with passlib's bcrypt or argon2, never in plain text.

Router-level dependencies

from fastapi import APIRouter

admin = APIRouter(prefix="/admin", dependencies=[Depends(current_user)])

@admin.get("/stats")
def stats():
    return {"users": 10}

app.include_router(admin)
# Write your solution here
Up next · Lesson 5Async, Databases and DeploymentWhen to use async def, talking to a database and running in production.