Skip to main content

1. FastAPI Authentication Landscape

Before implementing JWT, it is helpful to recognize the available authentication models:
  • HTTP Basic Authentication: Credentials (username/password) are sent with every single request in the header.
    • Best for: Internal service-to-service communication or simple development setups.
    • Drawback: High risk if headers are intercepted; repetitive database lookups.
  • Session-Based Authentication (Stateful): The server issues a Session ID stored in a database and sets a client cookie.
    • Best for: Traditional server-rendered web applications.
    • Drawback: Requires server-side storage (memory/database lookup per request), limiting scalability across distributed server nodes.
  • JWT Token-Based Authentication (Stateless - Recommended for APIs): The server issues a signed token to the client. The client stores it and attaches it to subsequent requests.
    • Best for: Modern REST APIs, single-page applications (SPAs), microservices, and mobile apps.
    • Advantage: Stateless. The server does not query a session database to verify user identity—it simply decodes and verifies the token’s digital signature using a secret key.

2. Deep Dive: What is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe string containing claims (user statements) that can be verified and trusted because it is digitally signed. A JWT consists of three parts separated by periods (.):
  1. Header: Defines token metadata (typically the signing algorithm, e.g., HS256, and token type, JWT).
  2. Payload: Contains claims about the user (e.g., user ID sub, name, roles, and expiration time exp).
    [!WARNING] The Payload is only Base64URL encoded, not encrypted. Anyone can decode a JWT and view its contents. Never store sensitive data (like passwords or API keys) in the payload.
  3. Signature: Created by hashing the encoded Header, encoded Payload, and a server-only SECRET_KEY using the designated algorithm. It prevents tampering: if even one character of the header or payload changes, the signature becomes invalid.

3. JWT Authentication Lifecycle


4. Step-by-Step JWT Implementation in FastAPI

This section details how to implement JWT authentication and Role-Based Access Control (RBAC) using SQLModel (or SQLAlchemy) in FastAPI.

Step 1: Install Dependencies

First, ensure you have the required python packages.
  • pyjwt handles JWT encoding and decoding.
  • passlib[bcrypt] provides password hashing algorithms.
  • python-multipart allows FastAPI to receive credentials via form submissions if using OAuth2 compatibility utilities.

Step 2: Database and User Model Setup

Create models.py defining the User schema.

Step 3: Password Encryption Logic

Create utility functions to hash passwords on registration and verify them during login.

Step 4: Token Generation Module

Define the engine that generates access tokens. It encodes payloads with a signature and set expiry limits.

Step 5: User Registration & Login Router

Build routes that handle registration (hashing the password) and login (matching credentials and issuing a JWT).

Step 6: Bearer Token Validation Dependency

Write the dependency function to secure individual endpoints. It validates the Bearer token in the incoming Authorization header and returns the current user record.

Step 7: Role-Based Access Control (RBAC)

To enforce authorization based on user roles, use a dependency factory. This lets you write clean, dynamic requirements directly in route definitions.

Route Protection Examples

Apply the authentication and role checks to API endpoints:

5. Testing Protected Endpoints in Swagger UI

FastAPI’s built-in Interactive Docs support direct JWT authentication testing:
  1. Open the documentation page at http://127.0.0.1:8000/docs.
  2. Use the /login endpoint with valid credentials to obtain a token.
  3. Copy the access_token string value from the JSON response.
  4. Scroll to the top of the docs page and click the green Authorize lock button.
  5. Paste your token in the Value input field and click Authorize.
  6. You can now call protected routes (like /users/me) directly from the browser; FastAPI will automatically attach the authorization header for subsequent operations.