FastAPI: Get The Current User From An Access Token

Alex Johnson
-
FastAPI: Get The Current User From An Access Token

Hey everyone! ๐Ÿ‘‹ Today, we're diving into a super common scenario in building APIs with FastAPI: how to grab the current authenticated user from an access token. This is a crucial part of securing your API and ensuring that only authorized users can access specific resources. We'll walk through creating a FastAPI dependency that handles the extraction of the user information, making your code cleaner and easier to maintain. Let's get started! ๐Ÿš€

Setting the Stage: The Need for a current_user Dependency

When building APIs, you often need to know who the user is making a request. This is essential for implementing features like user-specific data access, personalization, and authorization. A common way to handle authentication is through access tokens. These tokens are typically generated after a user successfully logs in and are then included in subsequent requests to identify the user.

FastAPI provides a powerful mechanism for handling these kinds of tasks: dependencies. Dependencies allow you to encapsulate reusable logic and inject it into your route functions. In our case, we'll create a dependency called current_user that does the following:

  1. Extracts the access token from the request (usually from the Authorization header).
  2. Validates the token to ensure it's valid and hasn't expired. This might involve checking the token against a database or using a cryptographic signature.
  3. Retrieves the user information associated with the token. This could involve looking up the user in a database based on the token's claims (e.g., user ID).
  4. Returns the user object, making it available to your route functions. If the token is invalid, it raises an HTTPException to indicate unauthorized access.

This approach has several benefits. First, it keeps your route functions clean by separating authentication logic from your business logic. Second, it makes it easy to reuse the authentication logic across multiple routes. Third, it improves the maintainability of your code because all the authentication-related code is centralized in the dependency.

Let's break down how we can create this in FastAPI.

Crafting the current_user Dependency

Alright, let's get into the nitty-gritty of building the current_user dependency. Here's a step-by-step guide:

1. Import Necessary Libraries

First, we'll import the necessary modules. We'll need FastAPI, Depends, and HTTPException from fastapi. We'll also need a way to handle the authentication, let's use jwt from jose to decode our token:

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from jose.utils import base64url_decode


# Add any models or data structures you'll use here

2. Define the OAuth2PasswordBearer

We use OAuth2PasswordBearer to handle the access token. This helper class will automatically extract the token from the Authorization header.

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

3. Implement the current_user Dependency

Now, the core of our solution โ€“ the current_user dependency function. This is where all the magic happens.

# Replace with your actual secret key and algorithm
SECRET_KEY = "YOUR_SECRET_KEY"
ALGORITHM = "HS256"


def current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
        # Add user retrieval logic here
        # Example:
        # user = get_user(username)
        # if user is None:
        #     raise credentials_exception

        return {"username": username}
    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

Let's go through this step-by-step:

  • token: str = Depends(oauth2_scheme): This line injects the access token into the current_user function. The OAuth2PasswordBearer takes care of extracting the token from the Authorization header.
  • try...except: This block handles potential errors during token validation. If anything goes wrong (e.g., the token is invalid, expired, or the signature doesn't match), it raises an HTTPException with a 401 Unauthorized status code.
  • jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]): This is where the token is actually decoded. It verifies the token's signature and checks for any tampering. You'll need to replace `

You may also like