0
0
FastapiHow-ToBeginner · 4 min read

How to Use API Key Authentication in FastAPI

In FastAPI, use APIKeyHeader or APIKeyQuery from fastapi.security to extract the API key from requests. Then, create a dependency that validates the key and use it in your route to protect endpoints.
📐

Syntax

FastAPI provides security utilities like APIKeyHeader and APIKeyQuery to read API keys from headers or query parameters. You create a dependency function that checks if the provided key matches your expected key. This dependency is added to routes to enforce authentication.

  • APIKeyHeader(name='X-API-Key'): Reads API key from a header named 'X-API-Key'.
  • APIKeyQuery(name='api_key'): Reads API key from query parameter 'api_key'.
  • Dependency function raises HTTPException if key is invalid.
python
from fastapi import Depends, FastAPI, HTTPException, Security
from fastapi.security.api_key import APIKeyHeader
from starlette.status import HTTP_403_FORBIDDEN

API_KEY = "mysecretkey"
API_KEY_NAME = "X-API-Key"
api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)

async def get_api_key(api_key_header: str = Security(api_key_header)):
    if api_key_header == API_KEY:
        return api_key_header
    else:
        raise HTTPException(
            status_code=HTTP_403_FORBIDDEN, detail="Could not validate API key"
        )
💻

Example

This example shows a FastAPI app with one protected endpoint that requires a valid API key in the X-API-Key header. If the key is missing or wrong, the server returns a 403 error.

python
from fastapi import Depends, FastAPI, HTTPException, Security
from fastapi.security.api_key import APIKeyHeader
from starlette.status import HTTP_403_FORBIDDEN

app = FastAPI()

API_KEY = "mysecretkey"
API_KEY_NAME = "X-API-Key"
api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)

async def get_api_key(api_key_header: str = Security(api_key_header)):
    if api_key_header == API_KEY:
        return api_key_header
    else:
        raise HTTPException(
            status_code=HTTP_403_FORBIDDEN, detail="Could not validate API key"
        )

@app.get("/protected")
async def protected_route(api_key: str = Depends(get_api_key)):
    return {"message": "You have access", "api_key": api_key}
Output
GET /protected with header X-API-Key: mysecretkey Response: {"message": "You have access", "api_key": "mysecretkey"} GET /protected without header or wrong key Response: 403 Forbidden {"detail": "Could not validate API key"}
⚠️

Common Pitfalls

  • Forgetting to set auto_error=False in APIKeyHeader causes FastAPI to return 401 automatically instead of your custom error.
  • Not raising HTTPException when the key is invalid lets unauthorized users access endpoints.
  • Using Depends instead of Security for the API key dependency can cause issues with OpenAPI docs and security scopes.
  • Hardcoding API keys in code is insecure; consider environment variables or secrets management.
python
from fastapi import Security
from fastapi.security.api_key import APIKeyHeader

# Wrong: auto_error=True (default) causes automatic 401
api_key_header_wrong = APIKeyHeader(name="X-API-Key")

# Right: auto_error=False to handle errors manually
api_key_header_right = APIKeyHeader(name="X-API-Key", auto_error=False)

# Wrong: Using Depends instead of Security
# async def get_key_wrong(api_key: str = Depends(api_key_header_right)):
#     ...

# Right: Use Security for API key
# async def get_key_right(api_key: str = Security(api_key_header_right)):
#     ...
📊

Quick Reference

Remember these key points when using API key authentication in FastAPI:

  • Use APIKeyHeader or APIKeyQuery to read keys.
  • Set auto_error=False to customize error handling.
  • Use Security dependency for API keys, not Depends.
  • Raise HTTPException with 403 status if key is invalid.
  • Protect routes by adding the API key dependency.

Key Takeaways

Use fastapi.security.APIKeyHeader or APIKeyQuery to extract API keys from requests.
Create a dependency with Security that validates the API key and raises HTTPException if invalid.
Set auto_error=False to control error responses manually.
Add the API key dependency to routes to protect them.
Avoid hardcoding keys in code; use environment variables for better security.