> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Ajoutez l’authentification Auth0 à une application Web Flask avec une fonctionnalité de connexion, des routes protégées et des profils utilisateur

# Ajoutez la fonctionnalité de connexion à votre application Flask

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<HowToSchema />

<Note>
  **Prérequis :** Avant de commencer, assurez-vous d’avoir installé les éléments suivants :

  * **[Python](https://www.python.org/downloads/)** 3.9 ou une version ultérieure
  * **[pip](https://pip.pypa.io/en/stable/installation/)** 20.0 ou une version ultérieure
  * **[jq](https://jqlang.org/)** - Requis pour configurer Auth0 CLI

  **Compatibilité des versions de Flask :** Ce guide de démarrage rapide utilise **Flask 2.0+** avec l’extra `[async]` pour la prise en charge de l’asynchrone.
</Note>

<div id="get-started">
  ## Pour commencer
</div>

Ce guide de démarrage rapide explique comment ajouter l’authentification Auth0 à une application Flask. Vous créerez une application Web sécurisée avec une fonctionnalité de connexion, des routes protégées et l’accès au profil de l’utilisateur à l’aide du [SDK WebApp Python d’Auth0](https://github.com/auth0/auth0-server-python).

<Steps>
  <Step title="Configurez votre environnement" stepNumber={1}>
    Créez un nouveau répertoire pour votre projet Flask :

    ```bash theme={null}
    mkdir auth0-flask-app && cd auth0-flask-app
    ```

    Créez un environnement virtuel :

    ```bash theme={null}
    python -m venv venv
    source venv/bin/activate  # Sur Windows : venv\Scripts\activate
    ```
  </Step>

  <Step title="Installez les dépendances" stepNumber={2}>
    Créez `requirements.txt` pour répertorier vos dépendances :

    ```txt requirements.txt theme={null}
    auth0-server-python>=1.0.0b7
    flask[async]>=2.0.0
    python-dotenv>=1.0.0
    ```

    Le fichier `requirements.txt` répertorie toutes les dépendances du projet. Pour les installer, exécutez :

    ```bash theme={null}
    pip install -r requirements.txt
    ```
  </Step>

  <Step title="Configurez votre application Auth0" stepNumber={3}>
    Ensuite, créez une nouvelle application sur votre locataire Auth0 et ajoutez les variables d'environnement à votre projet.

    Vous pouvez effectuer cette opération automatiquement en exécutant une commande CLI ou manuellement via le Auth0 Dashboard :

    <Tabs>
      <Tab title="CLI">
        Exécutez la commande shell suivante à la racine de votre projet pour créer une application Auth0 et générer un fichier `.env` :

        <CodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="My Flask App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t regular -c http://localhost:5000/callback -l http://localhost:5000 -o http://localhost:5000 --reveal-secrets --json > app-details.json && CLIENT_ID=$(python3 -c "import json; print(json.load(open('app-details.json'))['client_id'])") && CLIENT_SECRET=$(python3 -c "import json; print(json.load(open('app-details.json'))['client_secret'])") && DOMAIN=$(auth0 tenants list --json | python3 -c "import sys, json; print([t['name'] for t in json.load(sys.stdin) if t.get('active')][0])") && SECRET=$(openssl rand -hex 64) && echo "AUTH0_DOMAIN=${DOMAIN}" > .env && echo "AUTH0_CLIENT_ID=${CLIENT_ID}" >> .env && echo "AUTH0_CLIENT_SECRET=${CLIENT_SECRET}" >> .env && echo "AUTH0_SECRET=${SECRET}" >> .env && echo "AUTH0_REDIRECT_URI=http://localhost:5000/callback" >> .env && rm app-details.json && echo ".env file created with your Auth0 details:" && cat .env
          ```

          ```shellscript Windows theme={null}
          $AppName = "My Flask App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t regular -c http://localhost:5000/callback -l http://localhost:5000 -o http://localhost:5000 --reveal-secrets --json | Set-Content -Path app-details.json; $ClientId = (Get-Content -Raw app-details.json | ConvertFrom-Json).client_id; $ClientSecret = (Get-Content -Raw app-details.json | ConvertFrom-Json).client_secret; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; $Secret = [System.Convert]::ToHexString([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(64)).ToLower(); Set-Content -Path .env -Value "AUTH0_DOMAIN=$Domain"; Add-Content -Path .env -Value "AUTH0_CLIENT_ID=$ClientId"; Add-Content -Path .env -Value "AUTH0_CLIENT_SECRET=$ClientSecret"; Add-Content -Path .env -Value "AUTH0_SECRET=$Secret"; Add-Content -Path .env -Value "AUTH0_REDIRECT_URI=http://localhost:5000/callback"; Remove-Item app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Dashboard">
        Avant de commencer, créez un fichier `.env` à la racine de votre projet :

        ```bash .env theme={null}
        # Configuration Auth0
        AUTH0_DOMAIN=YOUR_AUTH0_DOMAIN
        AUTH0_CLIENT_ID=YOUR_CLIENT_ID
        AUTH0_CLIENT_SECRET=YOUR_CLIENT_SECRET
        AUTH0_SECRET=YOUR_GENERATED_SECRET
        AUTH0_REDIRECT_URI=http://localhost:5000/callback
        ```

        1. Accédez à [Auth0 Dashboard](https://manage.auth0.com/dashboard/) → **Applications** → **Applications**
        2. Cliquez sur **Create Application**
        3. Donnez un nom à votre application (par ex., "My Flask App") et sélectionnez **Regular Web Application**
        4. Cliquez sur **Create**
        5. Dans l’onglet **Settings**, configurez les éléments suivants :
           * **Allowed Callback URLs**: `http://localhost:5000/callback`
           * **Allowed Logout URLs**: `http://localhost:5000`
           * **Allowed Web Origins**: `http://localhost:5000`
        6. Cliquez sur **Save Changes**
        7. Remplacez `YOUR_AUTH0_DOMAIN` dans `.env` par votre **Domaine** indiqué dans l’onglet **Settings** (par ex., `your-tenant.auth0.com`)
        8. Remplacez `YOUR_CLIENT_ID` dans `.env` par votre **ID client**
        9. Remplacez `YOUR_CLIENT_SECRET` dans `.env` par votre **Secret client**

        Générez un secret sécurisé pour `AUTH0_SECRET` :

        ```bash theme={null}
        openssl rand -hex 64
        ```

        <Info>
          **Important :** Ne validez jamais votre fichier `.env` dans votre système de contrôle de version. Ajoutez-le à `.gitignore`.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Créer la configuration d’authentification, les routes et les modèles" stepNumber={4}>
    Créer des fichiers

    ```bash theme={null}
    mkdir templates static && touch app.py auth.py templates/index.html templates/profile.html static/style.css
    ```

    Et ajoutez les extraits de code suivants :

    <AuthCodeGroup>
      ```python auth.py expandable lines theme={null}
      import os
      from auth0_server_python.auth_server.server_client import ServerClient
      from dotenv import load_dotenv

      load_dotenv()

      # Stockage simple en mémoire pour le développement
      # Pour la production, utilisez Redis, PostgreSQL ou un autre stockage persistant
      class MemoryStateStore:
          """In-memory state store for session data (development only)"""
          def __init__(self):
              self._data = {}
          
          async def get(self, key, options=None):
              return self._data.get(key)
          
          async def set(self, key, value, options=None):
              self._data[key] = value
          
          async def delete(self, key, options=None):
              self._data.pop(key, None)
          
          async def delete_by_logout_token(self, claims, options=None):
              # Pour la prise en charge de la déconnexion par canal arrière
              pass

      class MemoryTransactionStore:
          """In-memory transaction store for OAuth flows (development only)"""
          def __init__(self):
              self._data = {}
          
          async def get(self, key, options=None):
              return self._data.get(key)
          
          async def set(self, key, value, options=None):
              self._data[key] = value
          
          async def delete(self, key, options=None):
              self._data.pop(key, None)

      # Initialiser les stores
      state_store = MemoryStateStore()
      transaction_store = MemoryTransactionStore()

      # Initialiser le ServerClient Auth0
      auth0 = ServerClient(
          domain=os.getenv('AUTH0_DOMAIN'),
          client_id=os.getenv('AUTH0_CLIENT_ID'),
          client_secret=os.getenv('AUTH0_CLIENT_SECRET'),
          secret=os.getenv('AUTH0_SECRET'),
          redirect_uri=os.getenv('AUTH0_REDIRECT_URI'),
          state_store=state_store,
          transaction_store=transaction_store,
          authorization_params={
              'scope': 'openid profile email',
              'audience': os.getenv('AUTH0_AUDIENCE', '')  # Facultatif : pour l'accès à l'API
          }
      )
      ```

      ```python app.py expandable lines theme={null}
      import os
      from flask import Flask, redirect, render_template, request, url_for, g
      from auth0_server_python.auth_types import LogoutOptions
      from auth import auth0
      from dotenv import load_dotenv

      load_dotenv()

      app = Flask(__name__)
      app.secret_key = os.getenv('AUTH0_SECRET')

      # Configurer la session pour Auth0
      app.config.update(
          SESSION_COOKIE_SECURE=False,  # Mettre à True en production avec HTTPS
          SESSION_COOKIE_HTTPONLY=True,
          SESSION_COOKIE_SAMESITE='Lax',
      )

      @app.before_request
      def store_request_response():
          """Make request/response available for Auth0 SDK"""
          g.store_options = {"request": request}

      @app.route('/')
      async def index():
          """Home page - shows login button or user profile"""
          user = await auth0.get_user(g.store_options)
          return render_template('index.html', user=user)

      @app.route('/login')
      async def login():
          """Redirect to Auth0 login"""
          authorization_url = await auth0.start_interactive_login({}, g.store_options)
          return redirect(authorization_url)

      @app.route('/callback')
      async def callback():
          """Handle Auth0 callback after login"""
          try:
              result = await auth0.complete_interactive_login(str(request.url), g.store_options)
              return redirect(url_for('index'))
          except Exception as e:
              return f"Authentication error: {str(e)}", 400

      @app.route('/profile')
      async def profile():
          """Protected route - shows user profile"""
          user = await auth0.get_user(g.store_options)
          
          if not user:
              return redirect(url_for('login'))
          
          return render_template('profile.html', user=user)

      @app.route('/logout')
      async def logout():
          """Logout and redirect to Auth0 logout"""
          options = LogoutOptions(return_to=url_for("index", _external=True))
          logout_url = await auth0.logout(options, g.store_options)
          return redirect(logout_url)

      if __name__ == '__main__':
          app.run(debug=True, port=5000)
      ```

      ```html templates/index.html expandable lines theme={null}
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Flask + Auth0</title>
      <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
      </head>
      <body>
      <div class="container">
          <div class="card">
              <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                   alt="Auth0 Logo" class="logo">
              <h1>Flask + Auth0</h1>
              
              {% if user %}
                  <div class="logged-in">
                      <p class="success">✅ Successfully logged in!</p>
                      <div class="user-info">
                          {% if user.picture %}
                          <img src="{{ user.picture }}" alt="Profile" class="profile-pic">
                          {% endif %}
                          <h2>{{ user.name }}</h2>
                          <p>{{ user.email }}</p>
                      </div>
                      <a href="/profile" class="button">View Full Profile</a>
                      <a href="/logout" class="button logout">Log Out</a>
                  </div>
              {% else %}
                  <div class="logged-out">
                      <p>Welcome! Please log in to access your protected content.</p>
                      <a href="/login" class="button">Log In</a>
                  </div>
              {% endif %}
          </div>
      </div>
      </body>
      </html>
      ```

      ```html templates/profile.html expandable lines theme={null}
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>User Profile - Flask + Auth0</title>
      <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
      </head>
      <body>
      <div class="container">
          <div class="card">
              <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                   alt="Auth0 Logo" class="logo">
              <h1>User Profile</h1>
              
              <div class="profile-details">
                  {% if user.picture %}
                  <img src="{{ user.picture }}" alt="Profile" class="profile-pic-large">
                  {% endif %}
                  
                  <div class="profile-info">
                      <h2>{{ user.name }}</h2>
                      <p class="email">{{ user.email }}</p>
                      
                      <div class="profile-data">
                          <h3>Profile Information</h3>
                          <dl>
                              <dt>User ID:</dt>
                              <dd>{{ user.sub }}</dd>
                              
                              {% if user.nickname %}
                              <dt>Nickname:</dt>
                              <dd>{{ user.nickname }}</dd>
                              {% endif %}
                              
                              {% if user.updated_at %}
                              <dt>Last Updated:</dt>
                              <dd>{{ user.updated_at }}</dd>
                              {% endif %}
                          </dl>
                      </div>
                  </div>
              </div>
              
              <div class="actions">
                  <a href="/" class="button">Back to Home</a>
                  <a href="/logout" class="button logout">Log Out</a>
              </div>
          </div>
      </div>
      </body>
      </html>
      ```

      ```css static/style.css expandable lines theme={null}
      @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

      * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      }

      body {
      font-family: 'Inter', sans-serif;
      background: linear-gradient(135deg, #1a1e27 0%, #2d313c 100%);
      min-height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #e2e8f0;
      padding: 20px;
      }

      .container {
      width: 100%;
      max-width: 600px;
      }

      .card {
      background-color: #262a33;
      border-radius: 20px;
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
      padding: 3rem;
      animation: fadeInScale 0.6s ease-out;
      }

      @keyframes fadeInScale {
      from {
          opacity: 0;
          transform: scale(0.95);
      }
      to {
          opacity: 1;
          transform: scale(1);
      }
      }

      .logo {
      width: 160px;
      margin: 0 auto 2rem;
      display: block;
      animation: slideDown 0.8s ease-out;
      }

      @keyframes slideDown {
      from {
          opacity: 0;
          transform: translateY(-30px);
      }
      to {
          opacity: 1;
          transform: translateY(0);
      }
      }

      h1 {
      font-size: 2.5rem;
      font-weight: 700;
      text-align: center;
      margin-bottom: 2rem;
      color: #f7fafc;
      text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
      }

      h2 {
      font-size: 1.8rem;
      font-weight: 600;
      margin: 0.5rem 0;
      color: #f7fafc;
      }

      h3 {
      font-size: 1.3rem;
      font-weight: 600;
      margin-top: 1.5rem;
      margin-bottom: 1rem;
      color: #cbd5e0;
      }

      .logged-in, .logged-out {
      text-align: center;
      }

      .logged-out p {
      font-size: 1.2rem;
      color: #cbd5e0;
      margin-bottom: 2rem;
      line-height: 1.6;
      }

      .success {
      font-size: 1.5rem;
      color: #68d391;
      font-weight: 600;
      margin-bottom: 1.5rem;
      }

      .user-info {
      background-color: #2d313c;
      border-radius: 15px;
      padding: 2rem;
      margin: 2rem 0;
      }

      .profile-pic {
      width: 80px;
      height: 80px;
      border-radius: 50%;
      margin-bottom: 1rem;
      border: 3px solid #63b3ed;
      object-fit: cover;
      }

      .profile-pic-large {
      width: 120px;
      height: 120px;
      border-radius: 50%;
      margin-bottom: 1rem;
      border: 4px solid #63b3ed;
      object-fit: cover;
      }

      .user-info p, .email {
      color: #a0aec0;
      font-size: 1.1rem;
      }

      .button {
      display: inline-block;
      padding: 1rem 2.5rem;
      font-size: 1.1rem;
      font-weight: 600;
      border-radius: 10px;
      border: none;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
      text-decoration: none;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      margin: 0.5rem;
      background-color: #63b3ed;
      color: #1a1e27;
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
      }

      .button:hover {
      background-color: #4299e1;
      transform: translateY(-3px);
      box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
      }

      .button.logout {
      background-color: #fc8181;
      }

      .button.logout:hover {
      background-color: #e53e3e;
      }

      .profile-details {
      text-align: center;
      }

      .profile-info {
      background-color: #2d313c;
      border-radius: 15px;
      padding: 2rem;
      margin-top: 1.5rem;
      }

      .profile-data {
      margin-top: 2rem;
      text-align: left;
      }

      .profile-data dl {
      display: grid;
      grid-template-columns: 150px 1fr;
      gap: 1rem;
      margin-top: 1rem;
      }

      .profile-data dt {
      font-weight: 600;
      color: #cbd5e0;
      }

      .profile-data dd {
      color: #a0aec0;
      word-break: break-all;
      }

      .actions {
      margin-top: 2rem;
      display: flex;
      justify-content: center;
      flex-wrap: wrap;
      }

      @media (max-width: 600px) {
      .card {
          padding: 2rem;
      }

      h1 {
          font-size: 2rem;
      }

      .button {
          padding: 0.8rem 2rem;
          font-size: 1rem;
      }

      .logo {
          width: 120px;
      }

      .profile-data dl {
          grid-template-columns: 1fr;
          gap: 0.5rem;
      }

      .profile-data dt {
          margin-top: 1rem;
      }
      }
      ```
    </AuthCodeGroup>

    <Info>
      **Développement uniquement :** Cet exemple utilise de simples classes de stockage en mémoire (`MemoryStateStore` et `MemoryTransactionStore`) à des fins de démonstration. Ces mécanismes de stockage perdront toutes les données de session au redémarrage de votre application et ne fonctionneront pas dans des déploiements à instances multiples.

      **Pour les applications de production**, vous devez mettre en place un stockage persistant. Le SDK est indépendant du framework et vous oblige à fournir des implémentations personnalisées de `StateStore` et `TransactionStore`. Consultez les [exemples officiels de stockage du SDK](https://github.com/auth0/auth0-server-python/blob/main/examples/ConfigureStore.md) pour obtenir des directives détaillées sur la mise en œuvre de Redis, PostgreSQL ou d’autres solutions de stockage persistant.
    </Info>
  </Step>

  <Step title="Lancez votre application" stepNumber={5}>
    Démarrez le serveur de développement Flask :

    ```bash theme={null}
    python app.py
    ```

    Votre application sera accessible à l’adresse [http://localhost:5000](http://localhost:5000). Le SDK Auth0 prend automatiquement en charge les routes d’authentification.
  </Step>
</Steps>

<Check>
  **Point de contrôle**

  Vous devriez maintenant avoir une page de connexion Auth0 entièrement fonctionnelle qui s’exécute sur votre [localhost](http://localhost:5000/)
</Check>

***

<div id="advanced-usage">
  ## Utilisation avancée
</div>

<Accordion title="Accès aux jetons d’API">
  Si vous devez appeler une API protégée, récupérez un jeton d’accès :

  ```python theme={null}
  @app.route('/api-call')
  @require_auth
  async def api_call():
      try:
          # Récupérer le jeton d’accès pour votre API
          access_token = await auth0.get_access_token(
              audience='https://your-api.example.com',
              store_options=g.store_options
          )
          
          # Utiliser le jeton pour appeler votre API
          # headers = {'Authorization': f'Bearer {access_token}'}
          # response = requests.get('https://your-api.example.com/data', headers=headers)
          
          return f"Access token retrieved: {access_token[:20]}..."
      except Exception as e:
          return f"Error getting access token: {str(e)}", 500
  ```

  <Info>
    Pour utiliser cette fonctionnalité, vous devez :

    1. Définir `AUTH0_AUDIENCE` dans votre fichier `.env`
    2. Inclure `offline_access` dans vos scopes (pour les jetons d’actualisation)
    3. Mettre à jour `authorization_params` dans `auth.py` :
       ```python theme={null}
       authorization_params={
           'scope': 'openid profile email offline_access',
           'audience': os.getenv('AUTH0_AUDIENCE')
       }
       ```
  </Info>
</Accordion>

<Accordion title="Configuration d’un stockage personnalisé">
  Par défaut, le SDK utilise un stockage basé sur des cookies. Pour les environnements de production ayant des besoins particuliers (mise à l’échelle horizontale, partage de session entre services), vous pouvez configurer des backends de stockage personnalisés comme Redis ou PostgreSQL.

  **Quand utiliser un stockage personnalisé :**

  * Vous devez partager les sessions entre plusieurs serveurs
  * Vos données de session dépassent les limites de taille des cookies
  * Vous avez besoin d’une gestion centralisée des sessions pour la déconnexion par canal arrière

  **Exemple Redis :**

  ```python auth.py theme={null}
  from auth0_server_python.stores.redis_state_store import RedisStateStore
  import redis.asyncio as redis

  # Initialiser un magasin d’état personnalisé
  redis_client = redis.from_url(os.getenv('REDIS_URL', 'redis://localhost:6379'))
  state_store = RedisStateStore(
      secret=os.getenv('AUTH0_SECRET'),
      redis_client=redis_client
  )

  # Passer à ServerClient
  auth0 = ServerClient(
      domain=os.getenv('AUTH0_DOMAIN'),
      client_id=os.getenv('AUTH0_CLIENT_ID'),
      client_secret=os.getenv('AUTH0_CLIENT_SECRET'),
      secret=os.getenv('AUTH0_SECRET'),
      redirect_uri=os.getenv('AUTH0_REDIRECT_URI'),
      state_store=state_store,  # Stockage personnalisé
      authorization_params={'scope': 'openid profile email'}
  )
  ```

  <Info>
    Pour la plupart des applications, le stockage par défaut basé sur des cookies est suffisant. Le stockage personnalisé exige l’implémentation de l’interface `StateStore`. Consultez les [exemples du SDK](https://github.com/auth0/auth0-server-python/blob/main/examples/ConfigureStore.md) pour obtenir des implémentations détaillées.
  </Info>
</Accordion>

***

<div id="common-issues">
  ## Problèmes courants
</div>

<AccordionGroup>
  <Accordion title="MissingRequiredArgumentError">
    **Problème :** Vous voyez "MissingRequiredArgumentError: secret" au démarrage de l’application

    **Cause :** La variable d’environnement `AUTH0_SECRET` est absente ou ne se charge pas correctement.

    **Solution :**

    1. Vérifiez que votre fichier `.env` se trouve à la racine du projet
    2. Assurez-vous que `python-dotenv` est installé : `pip install python-dotenv`
    3. Générez un nouveau secret au besoin : `openssl rand -hex 64`
    4. Ajoutez-le à `.env` : `AUTH0_SECRET=your_generated_secret`
    5. Redémarrez votre application Flask
  </Accordion>

  <Accordion title="Erreur : URL de rappel invalide">
    **Problème :** Vous voyez l’erreur "Callback URL mismatch" ou "invalid\_request" lors de la connexion

    **Cause :** L’URI de redirection dans votre code ne correspond pas à celle enregistrée dans Auth0 Dashboard.

    **Solution :**

    1. Vérifiez votre fichier `.env` : `AUTH0_REDIRECT_URI=http://localhost:5000/callback`
    2. Accédez à [Auth0 Dashboard](https://manage.auth0.com/dashboard/) → Applications → Votre application → Settings
    3. Ajoutez `http://localhost:5000/callback` à **Allowed Callback URLs**
    4. Cliquez sur **Save Changes**
    5. Redémarrez votre application Flask
  </Accordion>

  <Accordion title="Erreurs liées à la boucle d’événements AsyncIO">
    **Problème :** Vous voyez "RuntimeError: This event loop is already running" ou des erreurs asynchrones semblables

    **Cause :** La prise en charge de l’asynchrone dans Flask 2.0+ peut poser problème avec certaines configurations.

    **Solution :**

    Installez Flask avec la prise en charge de l’asynchrone :

    ```bash theme={null}
    pip install "flask[async]"
    ```

    Redémarrez ensuite votre application Flask.
  </Accordion>

  <Accordion title="Erreurs « Module introuvable »">
    **Problème :** Vous voyez "ModuleNotFoundError: No module named 'auth0\_server\_python'" ou un message semblable

    **Cause :** Le SDK n’est pas installé ou l’environnement virtuel n’est pas activé.

    **Solution :**

    1. Assurez-vous que votre environnement virtuel est activé :
       ```bash theme={null}
       source venv/bin/activate  # macOS/Linux
       # ou
       venv\Scripts\activate  # Windows
       ```
    2. Installez le SDK :
       ```bash theme={null}
       pip install auth0-server-python "flask[async]" python-dotenv
       ```
    3. Vérifiez l’installation :

    ```bash theme={null}
    pip list | grep auth0
    ```
  </Accordion>

  <Accordion title="Erreur ClaimDecodingFailed">
    **Problème :** Vous voyez l’erreur "ClaimDecodingFailed" ou "Failed to decode claims" lors de l’authentification

    **Cause :** Le jeton d’identité ou le jeton d’accès reçu depuis Auth0 n’a pas pu être décodé correctement, souvent pour l’une des raisons suivantes :

    * format JWT invalide
    * données de session corrompues
    * algorithmes de signature incompatibles
    * décalage horaire entre votre serveur et Auth0

    **Solution :**

    1. Assurez-vous que votre `AUTH0_CLIENT_SECRET` est correct dans le fichier `.env`
    2. Vérifiez que l’heure de votre système est synchronisée (NTP) :
       ```bash theme={null}
       # macOS
       sudo sntp -sS time.apple.com

       # Linux
       sudo ntpdate -s time.nist.gov
       ```
    3. Effacez les témoins du navigateur et relancez l’authentification
    4. Vérifiez que `AUTH0_DOMAIN` n’inclut pas le préfixe `https://`
    5. Vérifiez que Auth0 Dashboard → Applications → Your App → Settings → Advanced → OAuth → JsonWebToken Signature Algorithm correspond à la configuration de votre SDK
  </Accordion>

  <Accordion title="Jeton expiré ou invalide">
    **Problème :** Vous voyez les erreurs "Token has expired" ou "invalid\_token"

    **Cause :** Le jeton d’accès ou le jeton d’identité a expiré, ou la session a pris fin.

    **Solution :**

    1. Le SDK gère automatiquement l’actualisation du jeton si vous incluez le scope `offline_access` :
       ```python theme={null}
       authorization_params={
           'scope': 'openid profile email offline_access',
       }
       ```
    2. Pour les API, assurez-vous de demander de nouveaux jetons :
       ```python theme={null}
       access_token = await auth0.get_access_token(
           audience='https://your-api.example.com',
           force_refresh=True  # Forcer l’actualisation au besoin
       )
       ```
    3. Réglez la durée de vie des jetons dans Auth0 Dashboard → Applications → Your App → Settings → Advanced → OAuth
    4. Implémentez une gestion appropriée des erreurs afin de rediriger les utilisateurs vers la connexion lorsque les jetons expirent
  </Accordion>

  <Accordion title="CORS et erreurs inter-origines">
    **Problème :** Vous voyez des erreurs CORS ou "Blocked by CORS policy" dans la console du navigateur

    **Cause :** L'origine de votre application n'est pas configurée correctement dans Auth0.

    **Solution :**

    1. Ajoutez votre origine dans Auth0 Dashboard → Applications → Your App → Settings :
       * **Allowed Web Origins**: `http://localhost:5000`
       * **Allowed Callback URLs**: `http://localhost:5000/callback`
       * **Allowed Logout URLs**: `http://localhost:5000`
    2. En production, ajoutez vos URL de production :
       ```
       https://yourdomain.com
       https://yourdomain.com/callback
       ```
    3. Assurez-vous que votre application Flask a une configuration CORS appropriée si vous appelez les API Auth0 à partir du JavaScript côté client :
       ```python theme={null}
       from flask_cors import CORS
       CORS(app, origins=['http://localhost:5000'])
       ```
  </Accordion>

  <Accordion title="Limite de requêtes dépassée">
    **Problème :** Vous voyez des erreurs "Trop de requêtes" ou "Rate limit exceeded"

    **Cause :** Votre application a dépassé les limites de requêtes d'Auth0 pour les demandes d'authentification.

    **Solution :**

    1. Consultez Auth0 Dashboard → Monitoring → Logs pour obtenir des détails sur les limites de requêtes
    2. Implémentez un délai d'attente exponentiel pour les nouvelles tentatives :
       ```python theme={null}
       import time
       from auth0_server_python.error import ApiError

       async def login_with_retry():
           max_retries = 3
           for attempt in range(max_retries):
               try:
                   return await auth0.start_interactive_login({}, g.store_options)
               except ApiError as e:
                   if e.status_code == 429 and attempt < max_retries - 1:
                       wait_time = 2 ** attempt
                       time.sleep(wait_time)
                   else:
                       raise
       ```
    3. Vérifiez les limites de votre forfait Auth0
    4. Optimisez le flux d'authentification pour réduire les demandes de jetons inutiles
    5. Mettez les jetons en cache de façon appropriée au lieu d'en demander fréquemment de nouveaux
  </Accordion>
</AccordionGroup>
