Security and Authentication Schemes
FastAPI provides a set of security utilities that integrate directly with the OpenAPI specification. These utilities allow you to define security requirements for your API, such as API keys, HTTP authentication, and OAuth2 flows, while automatically generating the corresponding documentation in Swagger UI.
API Key Authentication
To secure an endpoint using an API key, use the APIKeyHeader, APIKeyQuery, or APIKeyCookie classes from fastapi.security. These classes use the APIKey model from fastapi.openapi.models to define the security scheme in the OpenAPI document.
from fastapi import Depends, FastAPI
from fastapi.security import APIKeyHeader
app = FastAPI()
# Define the security scheme (e.g., a header named 'x-key')
header_scheme = APIKeyHeader(name="x-key")
@app.get("/items/")
async def read_items(key: str = Depends(header_scheme)):
return {"key": key}
Variations for API Keys
FastAPI supports three locations for API keys, as defined by APIKeyIn:
- Header:
APIKeyHeader(name="X-API-Key") - Query Parameter:
APIKeyQuery(name="api_key") - Cookie:
APIKeyCookie(name="session_id")
Each of these classes extracts the value from the request and provides it as a string to your dependency.
HTTP Bearer Authentication
For token-based authentication using the Authorization header with the Bearer scheme, use the HTTPBearer class. This class populates the OpenAPI securitySchemes using the HTTPBearer model.
from typing import Annotated
from fastapi import Depends, FastAPI
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
app = FastAPI()
security = HTTPBearer()
@app.get("/users/me")
def read_current_user(
credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
):
# credentials.scheme will be "Bearer"
# credentials.credentials will be the actual token
return {"token": credentials.credentials}
The HTTPBearer utility automatically checks for the Bearer prefix in the Authorization header. If it is missing or incorrect, it raises an HTTPException with a 401 status code.
OAuth2 Authentication Flows
FastAPI implements OAuth2 by providing classes that correspond to different OAuth2 flows. These classes use OAuth2Model and OAuthFlows to describe the authentication process in the OpenAPI schema.
OAuth2 with Password Flow
The most common flow for simple applications is the Password flow with Bearer tokens. Use OAuth2PasswordBearer to define the token URL and required scopes.
from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer
app = FastAPI()
# tokenUrl points to the path operation that provides the token
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):
return {"token": token}
OAuth2 with Authorization Code Flow
For third-party integrations, use OAuth2AuthorizationCodeBearer. This requires both an authorizationUrl and a tokenUrl.
from fastapi.security import OAuth2AuthorizationCodeBearer
oauth2_scheme = OAuth2AuthorizationCodeBearer(
authorizationUrl="https://example.com/auth",
tokenUrl="https://example.com/token"
)
Managing Scopes
You can define required scopes in your security scheme and access them in your dependencies using the SecurityScopes class.
from fastapi import Security
from fastapi.security import OAuth2PasswordBearer, SecurityScopes
oauth2_scheme = OAuth2PasswordBearer(
tokenUrl="token",
scopes={"read:items": "Read items", "write:items": "Create items"}
)
@app.get("/items/")
async def read_items(
security_scopes: SecurityScopes,
token: str = Security(oauth2_scheme, scopes=["read:items"])
):
# security_scopes.scopes contains ["read:items"]
return {"token": token, "scopes": security_scopes.scopes}
OpenID Connect
FastAPI provides an OpenIdConnect class for integrating with OpenID Connect providers. This class uses the OpenIdConnect model to include the openIdConnectUrl in the OpenAPI specification.
from fastapi.security import OpenIdConnect
oidc_scheme = OpenIdConnect(openIdConnectUrl="https://example.com/.well-known/openid-configuration")
[!WARNING] The
OpenIdConnectandHTTPDigestclasses in FastAPI are currently stubs for OpenAPI documentation purposes. They extract theAuthorizationheader but do not implement the full validation logic (e.g., fetching configuration from the URL or verifying signatures). You must implement the validation logic in your own dependency.
Optional Authentication
By default, FastAPI security utilities raise an error if the authentication credentials are missing. You can make authentication optional by setting auto_error=False.
from fastapi.security import APIKeyHeader
# If the header is missing, 'key' will be None instead of raising 401
optional_scheme = APIKeyHeader(name="x-key", auto_error=False)
@app.get("/items/")
async def read_items(key: str | None = Depends(optional_scheme)):
if key is None:
return {"message": "Anonymous user"}
return {"key": key}
Troubleshooting
OAuth2 Form Data
When implementing the token endpoint for OAuth2PasswordBearer, remember that the OAuth2 specification requires the credentials to be sent as form data (application/x-www-form-urlencoded), not JSON. Use the OAuth2PasswordRequestForm dependency to handle this:
from fastapi import Depends
from fastapi.security import OAuth2PasswordRequestForm
@app.post("/token")
async def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
# Access form_data.username and form_data.password
return {"access_token": "secret", "token_type": "bearer"}
Security Scheme Naming
The scheme_name parameter in security classes (like APIKeyHeader or OAuth2) determines the key used in the components/securitySchemes section of the OpenAPI document. If not provided, it defaults to the class name. Use unique scheme_name values if you define multiple security schemes of the same type.