auth0-fastapi-api

À utiliser pour sécuriser les endpoints d'API FastAPI avec validation de token JWT Bearer, vérifications de portée/permissions ou auth sans état — intègre auth0-fastapi-api pour les REST APIs recevant des access tokens depuis des SPAs, applications mobiles ou autres clients. Gère également la liaison de token DPoP (proof-of-possession). Se déclenche sur : Auth0FastAPI, FastAPI API auth, JWT validation, require_auth, DPoP.

npx skills add https://github.com/auth0/agent-skills --skill auth0-fastapi-api

Intégration Auth0 FastAPI API

Protégez les endpoints FastAPI avec la validation des tokens d'accès JWT en utilisant auth0-fastapi-api.

Note : Ce SDK est actuellement en bêta. La surface API peut changer avant la version stable 1.0. Consultez PyPI pour la dernière version. Nécessite Python >= 3.9 et FastAPI >= 0.115.11.


Prérequis

  • Application FastAPI (Python 3.9+)
  • Ressource API Auth0 configurée (pas une Application — doit être une API)
  • Si vous n'avez pas encore Auth0, utilisez d'abord le skill auth0-quickstart

Quand ne PAS l'utiliser

  • Applications web rendues côté serveur — Utilisez un flux login/logout basé sur les sessions
  • Single Page Applications — Utilisez auth0-react, auth0-vue ou auth0-angular pour l'authentification côté client
  • Applications mobiles — Utilisez auth0-react-native ou auth0-android
  • Émission de tokens — Ce skill sert à valider les tokens d'accès, pas à les émettre

Démarrage Rapide

1. Installer le SDK

pip install auth0-fastapi-api python-dotenv

2. Créer une API Auth0

Vous avez besoin d'une API (pas une Application) dans Auth0.

STOP — demandez à l'utilisateur avant de continuer.

Posez exactement cette question et attendez sa réponse avant de rien faire d'autre :

« Comment souhaiteriez-vous créer la ressource API Auth0 ?

  1. Automatisé — Je vais exécuter des scripts Auth0 CLI qui créent la ressource et écrivent les valeurs exactes dans votre .env automatiquement.
  2. Manuel — Vous créez l'API vous-même dans le Auth0 Dashboard (ou via auth0 apis create) et me fournissez le Domain et l'Audience.

Que préférez-vous ? (1 = Automatisé / 2 = Manuel) »

Ne passez à aucune étape de configuration tant que l'utilisateur n'a pas répondu. Ne pas défaut sur manuel.

Si l'utilisateur a choisi Automatisé, suivez le Guide d'Installation pour les scripts CLI complets. Le chemin automatisé écrit .env pour vous — passez l'étape 3 ci-dessous et allez directement à l'étape 4.

Si l'utilisateur a choisi Manuel, suivez le Guide d'Installation (section Configuration Manuelle) pour les instructions complètes. Puis continuez avec l'étape 3 ci-dessous.

Référence rapide pour la création manuelle d'une API :

# Utiliser Auth0 CLI
auth0 apis create \
  --name "My FastAPI API" \
  --identifier https://my-api.example.com

Ou créez manuellement dans Auth0 Dashboard → Applications → APIs

3. Configurer l'Environnement

Créez .env :

AUTH0_DOMAIN=your-tenant.us.auth0.com
AUTH0_AUDIENCE=https://your-api.example.com

AUTH0_DOMAIN est votre domaine de tenant Auth0 (sans https://). AUTH0_AUDIENCE est l'identifiant API que vous avez défini lors de la création de la ressource API dans Auth0.

4. Initialiser Auth0

import os
from fastapi import FastAPI, Depends
from fastapi_plugin import Auth0FastAPI
from dotenv import load_dotenv

load_dotenv()

app = FastAPI()

auth0 = Auth0FastAPI(
    domain=os.getenv("AUTH0_DOMAIN"),
    audience=os.getenv("AUTH0_AUDIENCE"),
)

Créez une instance Auth0FastAPI par application et réutilisez-la sur toutes les routes. Ne codez jamais le domaine ou l'audience — utilisez toujours les variables d'environnement.

5. Protéger les Routes

# Requiert n'importe quel token d'accès valide
@app.get("/api/private")
async def private(claims: dict = Depends(auth0.require_auth())):
    return {"user": claims["sub"]}

# Aucune authentification requise
@app.get("/api/public")
async def public():
    return {"message": "Public endpoint"}

La dépendance require_auth() valide le token Bearer, vérifie l'émetteur et l'audience, et retourne les claims JWT décodés.

Réponses d'erreur :

  • 400 invalid_request — En-tête Authorization manquant ou malformé
  • 401 invalid_token — Token expiré, signature invalide, émetteur/audience incorrect
  • 403 insufficient_scope — Token valide mais scopes requis manquants
  • 500 internal_server_error — Erreurs inattendues

Format du corps de réponse : {"detail": {"error": "...", "error_description": "..."}}

6. Protéger les Routes avec Vérification de Scope

# Requiert le scope read:messages
@app.get("/api/messages")
async def get_messages(claims: dict = Depends(auth0.require_auth(scopes="read:messages"))):
    return {"messages": []}

# Requiert les scopes read:data et write:data
@app.post("/api/data")
async def write_data(claims: dict = Depends(auth0.require_auth(scopes=["read:data", "write:data"]))):
    return {"created": True}

require_auth(scopes=...) vérifie le claim scope dans le JWT. Tous les scopes spécifiés doivent être présents (logique ET). Les scopes manquants retournent 403.

7. Accéder aux Claims du Token d'Accès

Les claims JWT décodés sont retournés directement par la dépendance :

@app.get("/api/profile")
async def profile(claims: dict = Depends(auth0.require_auth())):
    return {
        "sub": claims["sub"],       # ID utilisateur
        "scope": claims.get("scope"),  # scopes accordés
    }

Claims clés :

  • claims["sub"] — ID utilisateur/client
  • claims["scope"] — scopes accordés séparés par des espaces
  • claims["iss"] — émetteur (l'URL de votre domaine Auth0)
  • claims["aud"] — audience
  • claims["exp"] — timestamp d'expiration
  • claims["iat"] — timestamp d'émission

8. Protéger les Routes Sans Avoir Besoin des Claims

@app.get("/api/protected", dependencies=[Depends(auth0.require_auth())])
async def protected():
    return {"message": "You need a valid access token to see this."}

9. Tester l'API

# Sans token — attendez-vous à 401
curl http://localhost:8000/api/private

# Avec un token d'accès valide
curl http://localhost:8000/api/private \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Obtenez un token de test via le flux Client Credentials ou Auth0 Dashboard → APIs → onglet Test.


Erreurs Courantes

Erreur Solution
Codage en dur de domain ou audience dans le code Lisez toujours depuis les variables d'environnement — n'intégrez jamais les identifiants dans le code
Utiliser python-jose ou PyJWT directement Pas nécessaire ; auth0-fastapi-api gère toute la validation via JWKS
Analyser manuellement l'en-tête Authorization Le SDK extrait et valide le token automatiquement
Appeler jwt.decode() manuellement Le SDK vérifie les tokens par rapport au endpoint JWKS — ne vérifiez pas vous-même
Utiliser fastapi-users pour la validation JWT Auth0 Ce package est pour la gestion des utilisateurs, pas la vérification JWT Auth0
Créé une Application au lieu d'une API dans Auth0 Doit créer une ressource API (Applications → APIs) — une Application n'émet pas les tokens d'accès avec la bonne audience
Passer domain comme URL complète avec https:// domain doit être le domaine seul, par ex. my-tenant.us.auth0.com, pas https://my-tenant.us.auth0.com
Utiliser un ID token au lieu d'un access token Doit utiliser le access token pour l'authentification API — les ID tokens sont pour l'application client, pas pour l'autorisation API
Pas de configuration CORS pour les clients SPA Ajoutez CORSMiddleware pour permettre les requêtes depuis l'origine de votre frontend
os.getenv() retourne None silencieusement Assurez-vous que python-dotenv est installé et que load_dotenv() est appelé avant l'initialisation Auth0FastAPI — ou utilisez os.environ[] pour échouer rapidement

Support DPoP

Support intégré de la liaison des tokens proof-of-possession selon RFC 9449. DPoP est activé par défaut en mode mixte (accepte les tokens Bearer et DPoP). Consultez le Guide d'Intégration pour la configuration.


Skills Connexes

  • auth0-quickstart - Configuration Auth0 basique et détection du framework
  • auth0-mfa - Ajouter l'authentification multi-facteurs

Référence Rapide

Configuration Auth0FastAPI :

auth0 = Auth0FastAPI(
    domain=os.getenv("AUTH0_DOMAIN"),       # requis (ou utilisez domains)
    audience=os.getenv("AUTH0_AUDIENCE"),    # requis
    dpop_enabled=True,                       # défaut ; réglez False pour Bearer uniquement
    dpop_required=False,                     # défaut ; réglez True pour rejeter les tokens Bearer
)

Protection des routes :

Depends(auth0.require_auth())                    # n'importe quel token valide
Depends(auth0.require_auth(scopes="read:res"))   # scope unique
Depends(auth0.require_auth(scopes=["r", "w"]))   # tous les scopes requis

Accéder aux claims :

claims["sub"]           # ID utilisateur/client
claims["scope"]         # scopes séparés par des espaces

Variables d'environnement :

  • AUTH0_DOMAIN — votre domaine de tenant Auth0 (par ex. tenant.us.auth0.com)
  • AUTH0_AUDIENCE — l'identifiant de votre API (par ex. https://api.example.com)

Cas d'Usage Courants :

  • Protéger les routes → Depends(auth0.require_auth()) (voir étape 5)
  • Application des scopes → Depends(auth0.require_auth(scopes="...")) (voir étape 6)
  • Liaison des tokens DPoP → Guide d'Intégration
  • Configuration du reverse proxy → Guide d'Intégration
  • Configuration avancée → Référence API

Documentation Détaillée

  • Guide d'Installation — Configuration Auth0 CLI, configuration de l'environnement, obtention de tokens de test
  • Guide d'Intégration — DPoP, scopes, gestion des erreurs, reverse proxy, tests
  • Référence API — Options complètes du constructeur, signatures des méthodes, codes d'erreur

Références