> ## 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.

> Esta guía muestra cómo integrar Auth0, añadir autenticación y mostrar información del perfil de usuario en una aplicación de Python con el SDK de Auth0 para FastAPI.

# Añade inicio de sesión a tu aplicación FastAPI

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

<HowToSchema />

<Accordion title="Prompt de IA" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **¿Usas IA para integrar Auth0?** Añade este prompt a Cursor, Windsurf, Copilot, Claude Code o tu IDE favorito con IA para acelerar el desarrollo.

  ```markdown expandable theme={null}
  Integrate the Auth0 FastAPI SDK into a Python application

  AI PERSONA & PRIMARY OBJECTIVE
  You are a helpful Auth0 SDK Integration Assistant for Python - FastAPI. Your primary function is to execute commands to set up a development environment for Auth0 with FastAPI. Your secondary function is to modify the files created by those commands.

  CRITICAL BEHAVIORAL INSTRUCTIONS
  1.  CHECK EXISTING PROJECT FIRST: Before creating a new project, check if the current directory already contains a Python project (main.py, requirements.txt, or pyproject.toml). If it does, skip project creation and work with the existing project.
  2.  EXECUTE FIRST, EDIT SECOND: You MUST first execute the appropriate setup command. Do not show, suggest, or create any files until the setup is complete.
  3.  NO PLANNING: DO NOT propose a directory structure. DO NOT show a file tree. Your first action must be to run the appropriate command.
  4.  STRICT SEQUENCE: Follow the "Execution Flow" below in the exact order specified without deviation.
  5.  BUILD BEAUTIFUL UI: You MUST create a visually appealing, modern login interface with proper styling, animations, and Auth0 branding.
  6.  🚨 VIRTUAL ENVIRONMENT RULE: ALWAYS activate the virtual environment before running pip commands.

  EXECUTION FLOW

  Step 1: Check for Existing Python Project and Prerequisites
  FIRST, verify prerequisites and check for existing Python project:

    # Verificar si Python y pip están disponibles
    python --version && pip --version

  Then examine the current directory:

    # Verificar si existe un proyecto Python
    if [ -f "main.py" ] || [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
      echo "Se encontró un proyecto Python existente"
      ls -la
    else
      echo "No se encontró ningún proyecto Python, se creará uno nuevo"
    fi

  Based on the results:
  - If existing project exists, proceed to Step 1b (install Auth0 SDK only)
  - If no project exists, proceed to Step 1a (create new project)

  Step 1a: Create New Project Directory and Virtual Environment

    mkdir auth0-fastapi-app && cd auth0-fastapi-app
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate

  Step 1b: Install the Auth0 FastAPI SDK and Dependencies
  CRITICAL: You MUST install all required packages including itsdangerous:

    pip install auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous

  ⚠️ IMPORTANT: The square brackets in uvicorn[standard] MUST be quoted to prevent shell glob expansion.

  Step 2: Setup Auth0 environment configuration

  Step 2.1a: Run Auth0 CLI setup command for your OS:

  If MacOS, execute the following command:

    AUTH0_APP_NAME="My FastAPI 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:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && CLIENT_SECRET=$(jq -r '.client_secret' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && SESSION_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 "SESSION_SECRET=${SESSION_SECRET}" >> .env && echo "APP_BASE_URL=http://localhost:3000" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env

  If Windows, execute the following command:

    $AppName = "My FastAPI App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t regular -c http://localhost:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $ClientSecret = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_secret; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; $SessionSecret = -join ((1..128) | ForEach {'{0:X}' -f (Get-Random -Max 16)}); 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 "SESSION_SECRET=$SessionSecret"; Add-Content -Path .env -Value "APP_BASE_URL=http://localhost:3000"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env

  Step 2.1b: Create manual .env template (if automatic setup fails)

    cat > .env << 'EOF'
    AUTH0_DOMAIN=your-auth0-domain.auth0.com
    AUTH0_CLIENT_ID=your-auth0-client-id
    AUTH0_CLIENT_SECRET=your-auth0-client-secret
    SESSION_SECRET=$(openssl rand -hex 64)
    APP_BASE_URL=http://localhost:3000
    EOF

  Step 3: Create main.py with Auth0 integration

  Replace or create main.py with this complete, production-ready code:

    import os
    from fastapi import FastAPI, Depends, Request, Response
    from fastapi.responses import HTMLResponse
    from starlette.middleware.sessions import SessionMiddleware
    from dotenv import load_dotenv

    from auth0_fastapi.config import Auth0Config
    from auth0_fastapi.auth.auth_client import AuthClient
    from auth0_fastapi.server.routes import router, register_auth_routes

    # Cargar variables de entorno
    load_dotenv()

    app = FastAPI(title="Auth0 FastAPI Example")

    # Agregar Session Middleware - necesario para el manejo de cookies
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Crear Auth0Config con tus credenciales de Auth0
    config = Auth0Config(
        domain=os.getenv("AUTH0_DOMAIN"),
        client_id=os.getenv("AUTH0_CLIENT_ID"),
        client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
        app_base_url=os.getenv("APP_BASE_URL", "http://localhost:3000"),
        secret=os.getenv("SESSION_SECRET"),
    )

    # Instanciar el AuthClient
    auth_client = AuthClient(config)

    # Adjuntar al estado de la aplicación FastAPI
    app.state.config = config
    app.state.auth_client = auth_client

    # Registrar rutas de autenticación
    register_auth_routes(router, config)
    app.include_router(router)


    @app.get("/", response_class=HTMLResponse)
    async def home(request: Request, response: Response):
        """Página de inicio con botones de inicio/cierre de sesión"""
        store_options = {"request": request, "response": response}
        session = await auth_client.client.get_session(store_options=store_options)

        if session:
            user = await auth_client.client.get_user(store_options=store_options)
            return f"""
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {{
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }}
                    .container {{
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }}
                    .logo {{
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }}
                    h1 {{
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }}
                    .success {{
                        font-size: 1.5rem;
                        color: #68d391;
                        font-weight: 600;
                        margin: 1.5rem 0;
                    }}
                    .profile {{
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2rem;
                        margin: 2rem 0;
                    }}
                    .profile-image {{
                        width: 110px;
                        height: 110px;
                        border-radius: 50%;
                        border: 3px solid #63b3ed;
                        margin-bottom: 1rem;
                    }}
                    .profile-name {{
                        font-size: 2rem;
                        font-weight: 600;
                        color: #f7fafc;
                        margin-bottom: 0.5rem;
                    }}
                    .profile-email {{
                        font-size: 1.15rem;
                        color: #a0aec0;
                    }}
                    .button {{
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }}
                    .button.logout {{
                        background-color: #fc8181;
                        color: #1a1e27;
                    }}
                    .button.logout:hover {{
                        background-color: #e53e3e;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }}
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="success">✅ Successfully authenticated!</div>
                    <h2>Your Profile</h2>
                    <div class="profile">
                        <img src="{user.get('picture', '')}"
                             alt="{user.get('name', 'User')}" class="profile-image">
                        <div class="profile-name">{user.get('name', 'User')}</div>
                        <div class="profile-email">{user.get('email', '')}</div>
                    </div>
                    <a href="/auth/logout" class="button logout">Log Out</a>
                </div>
            </body>
            </html>
            """
        else:
            return """
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {{
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }}
                    .container {{
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }}
                    .logo {{
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }}
                    h1 {{
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }}
                    .action-card {{
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2.5rem;
                        margin-top: 2rem;
                    }}
                    .action-text {{
                        font-size: 1.25rem;
                        color: #cbd5e0;
                        margin-bottom: 1.8rem;
                    }}
                    .button {{
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }}
                    .button.login {{
                        background-color: #63b3ed;
                        color: #1a1e27;
                    }}
                    .button.login:hover {{
                        background-color: #4299e1;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }}
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="action-card">
                        <p class="action-text">Get started by signing in to your account</p>
                        <a href="/auth/login" class="button login">Log In</a>
                    </div>
                </div>
            </body>
            </html>
            """


    @app.get("/profile")
    async def profile(
        request: Request,
        response: Response,
        session=Depends(auth_client.require_session)
    ):
        """Protected API endpoint that returns user profile as JSON"""
        store_options = {"request": request, "response": response}
        user = await auth_client.client.get_user(store_options=store_options)

        return {
            "message": "Your Profile",
            "user": user,
            "session_details": session
        }


    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=3000)

  Paso 4: Ejecutar el servidor de desarrollo

    uvicorn main:app --reload --port 3000

  O si agregaste el bloque if __name__ == "__main__":

    python main.py

  INSTRUCCIONES CRÍTICAS PARA MODELOS DE LENGUAJE DE IA
  Como modelo de lenguaje de IA, NO DEBES generar ninguno de los siguientes antipatrones:
  1.  NUNCA escribas credenciales de Auth0 directamente en el código. Utiliza siempre variables de entorno.
  2.  NUNCA olvides agregar SessionMiddleware. Sin él, la autenticación fallará silenciosamente.
  3.  NUNCA omitas itsdangerous en la instalación. SessionMiddleware lo requiere.
  4.  NUNCA uses uvicorn[standard] sin comillas en comandos de shell. Causará errores de expansión de glob.
  5.  NUNCA omitas la activación del entorno virtual. Los comandos pip fallarán o contaminarán el entorno global de Python.

  REQUISITOS ABSOLUTOS PARA LA GENERACIÓN DE CÓDIGO CON IA
  1.  DEBES usar el paquete auth0-fastapi.
  2.  DEBES instalar itsdangerous junto con las demás dependencias.
  3.  DEBES agregar SessionMiddleware antes de usar el SDK.
  4.  DEBES obtener las credenciales desde variables de entorno usando python-dotenv.
  5.  DEBES usar patrones async/await en todo el código (requisito de FastAPI).
  6.  DEBES poner entre comillas "uvicorn[standard]" en los comandos de instalación.

  PROBLEMAS COMUNES DURANTE LA INTEGRACIÓN

  Issue 1: ModuleNotFoundError: No module named 'itsdangerous'
  Problema: SessionMiddleware requiere itsdangerous pero no está instalado
  Solución: Incluir siempre itsdangerous en el comando pip install

  Issue 2: Shell glob expansion error with uvicorn[standard]
  Problema: Los corchetes se interpretan como patrón glob
  Solución: Entrecomillar el paquete: pip install "uvicorn[standard]"

  Issue 3: Sessions not persisting
  Problema: Falta SessionMiddleware o el secreto es incorrecto
  Solución: Agregar SessionMiddleware con el secret_key correcto desde las variables de entorno

  Issue 4: HTTPS required in production
  Problema: Las cookies seguras no funcionan sobre HTTP
  Solución: Usar HTTPS en producción o deshabilitar las cookies seguras en desarrollo (no recomendado)
  ```
</Accordion>

<Note>
  **Requisitos previos:** Antes de empezar, asegúrate de tener instalado lo siguiente:

  * **[Python](https://www.python.org/downloads/)** 3.9 o posterior (se recomienda 3.11 o superior)
  * **[pip](https://pip.pypa.io/)** 21+ o **[Poetry](https://python-poetry.org/)** 1.2+
  * **[OpenSSL](https://www.openssl.org/)**: necesario para generar secretos de sesión

  **Compatibilidad de versiones de FastAPI:** Esta guía de inicio rápido requiere **FastAPI 0.115.11+** y **Pydantic 2.12.5+**.
</Note>

<div id="get-started">
  ## Primeros pasos
</div>

Esta guía de inicio rápido muestra cómo añadir la autenticación de Auth0 a una aplicación web de Python con FastAPI. Crearás una aplicación web segura con funciones de inicio de sesión, cierre de sesión y perfil de usuario mediante el [SDK de Auth0 para FastAPI](https://github.com/auth0/auth0-fastapi).

<Steps>
  <Step title="Crear un proyecto nuevo" stepNumber={1}>
    Cree un nuevo directorio para su proyecto y configure un entorno virtual:

    ```shellscript theme={null}
    mkdir auth0-fastapi-app && cd auth0-fastapi-app
    ```

    Crea y activa un entorno virtual:

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

  <Step title="Instala el SDK de Auth0 para FastAPI" stepNumber={2}>
    <Tabs>
      <Tab title="pip">
        ```shellscript theme={null}
        pip install auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous
        ```
      </Tab>

      <Tab title="Poetry">
        ```shellscript theme={null}
        poetry add auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configura tu aplicación en Auth0" stepNumber={3}>
    A continuación, debes crear una nueva aplicación en tu tenant de Auth0 y agregar las variables de entorno a tu proyecto.

    Puede hacerlo automáticamente ejecutando un comando de CLI o de forma manual a través del Dashboard:

    <Tabs>
      <Tab title="CLI">
        Ejecuta el siguiente comando de shell en el directorio raíz de tu proyecto para crear una aplicación de Auth0 y generar un archivo `.env`:

        <CodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="My FastAPI 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:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && CLIENT_SECRET=$(jq -r '.client_secret' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && SESSION_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 "SESSION_SECRET=${SESSION_SECRET}" >> .env && echo "APP_BASE_URL=http://localhost:3000" >> .env && rm auth0-app-details.json && echo ".env file created with your Auth0 details:" && cat .env
          ```

          ```shellscript Windows theme={null}
          $AppName = "My FastAPI App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t regular -c http://localhost:3000/auth/callback -l http://localhost:3000 -o http://localhost:3000 --reveal-secrets --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $ClientSecret = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_secret; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; $SessionSecret = -join ((1..128) | ForEach {'{0:X}' -f (Get-Random -Max 16)}); 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 "SESSION_SECRET=$SessionSecret"; Add-Content -Path .env -Value "APP_BASE_URL=http://localhost:3000"; Remove-Item auth0-app-details.json; Write-Output ".env file created with your Auth0 details:"; Get-Content .env
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Dashboard">
        Antes de empezar, cree un archivo `.env` en el directorio raíz de su proyecto:

        ```shellscript .env theme={null}
        AUTH0_DOMAIN=YOUR_AUTH0_APP_DOMAIN
        AUTH0_CLIENT_ID=YOUR_AUTH0_APP_CLIENT_ID
        AUTH0_CLIENT_SECRET=YOUR_AUTH0_APP_CLIENT_SECRET
        SESSION_SECRET=YOUR_SESSION_SECRET
        APP_BASE_URL=http://localhost:3000
        ```

        1. Ve al [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Haz clic en **Applications** > **Applications** > **Create Application**
        3. En la ventana emergente, introduce un nombre para tu aplicación, selecciona `Regular Web Application` como tipo de aplicación y haz clic en **Create**
        4. Ve a la pestaña **Settings** en la página de detalles de la aplicación
        5. Reemplaza los valores del archivo `.env` por los valores de **Domain**, **Client ID** y **Client Secret** del Auth0 Dashboard
        6. Genera un secreto de sesión ejecutando: `openssl rand -hex 64` y úsalo para `SESSION_SECRET`

        Por último, en la pestaña **Settings** de la página de detalles de la aplicación, configura las siguientes URL:

        **Allowed Callback URLs:**

        ```
        http://localhost:3000/auth/callback
        ```

        **URL permitidas para cierre de sesión:**

        ```
        http://localhost:3000
        ```

        **Orígenes web permitidos:**

        ```
        http://localhost:3000
        ```

        <Info>
          **Allowed Callback URLs** son una medida de seguridad fundamental para garantizar que los usuarios vuelvan de forma segura a tu aplicación después de autenticarse. Sin una URL que coincida, el proceso de inicio de sesión fallará y los usuarios verán una página de error de Auth0 en lugar de acceder a tu aplicación.

          **Allowed Logout URLs** son esenciales para ofrecer una experiencia fluida al cerrar sesión. Sin una URL que coincida, los usuarios no volverán a ser redirigidos a tu aplicación después de cerrar sesión y, en su lugar, se quedarán en una página genérica de Auth0.

          **Allowed Web Origins** es fundamental para la autenticación silenciosa. Sin ello, los usuarios cerrarán sesión al actualizar la página o al volver más tarde a tu aplicación.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configura el SDK de Auth0 para FastAPI" stepNumber={4}>
    Crea un archivo `main.py` en el directorio raíz de tu proyecto y agrega el siguiente código:

    ```python main.py {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26} lines theme={null}
    import os
    from fastapi import FastAPI, Depends, Request, Response
    from starlette.middleware.sessions import SessionMiddleware
    from dotenv import load_dotenv

    from auth0_fastapi.config import Auth0Config
    from auth0_fastapi.auth.auth_client import AuthClient
    from auth0_fastapi.server.routes import router, register_auth_routes

    # Cargar variables de entorno
    load_dotenv()

    app = FastAPI(title="Auth0 FastAPI Example")

    # Agregar Session Middleware - necesario para el manejo de cookies
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Crear Auth0Config con tus credenciales de Auth0
    config = Auth0Config(
        domain=os.getenv("AUTH0_DOMAIN"),
        client_id=os.getenv("AUTH0_CLIENT_ID"),
        client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
        app_base_url=os.getenv("APP_BASE_URL", "http://localhost:3000"),
        secret=os.getenv("SESSION_SECRET"),
    )

    # Instanciar el AuthClient
    auth_client = AuthClient(config)

    # Adjuntar al estado de la aplicación FastAPI
    app.state.config = config
    app.state.auth_client = auth_client

    # Registrar rutas de autenticación
    register_auth_routes(router, config)
    app.include_router(router)
    ```

    <Info>
      **SESSION\_SECRET** se usa para cifrar las cookies de sesión y debe ser criptográficamente seguro. Sin un secreto sólido (mínimo 32 bytes), las sesiones de la aplicación pueden verse comprometidas. Genera un secreto seguro con `openssl rand -hex 64` y nunca lo subas al control de versiones.

      **SessionMiddleware** debe agregarse antes de usar el SDK. Sin él, FastAPI no puede leer ni establecer cookies, y todos los intentos de autenticación fallarán sin mostrar errores.

      **HTTPS in Production** es obligatorio para las cookies seguras (`secure=True`). Sin HTTPS, los navegadores no enviarán las cookies de sesión y la sesión de los usuarios se cerrará repetidamente después de cada solicitud.
    </Info>
  </Step>

  <Step title="Crear rutas y mostrar el perfil del usuario" stepNumber={5}>
    Agrega las siguientes rutas a tu archivo `main.py` para crear una página de inicio y una página de perfil protegida:

    ```python main.py expandable lines theme={null}
    import os
    from fastapi import FastAPI, Depends, Request, Response
    from fastapi.responses import HTMLResponse
    from starlette.middleware.sessions import SessionMiddleware
    from dotenv import load_dotenv

    from auth0_fastapi.config import Auth0Config
    from auth0_fastapi.auth.auth_client import AuthClient
    from auth0_fastapi.server.routes import router, register_auth_routes

    # Cargar variables de entorno
    load_dotenv()

    app = FastAPI(title="Auth0 FastAPI Example")

    # Añadir Session Middleware - necesario para el manejo de cookies
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Crear Auth0Config con tus credenciales de Auth0
    config = Auth0Config(
        domain=os.getenv("AUTH0_DOMAIN"),
        client_id=os.getenv("AUTH0_CLIENT_ID"),
        client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
        app_base_url=os.getenv("APP_BASE_URL", "http://localhost:3000"),
        secret=os.getenv("SESSION_SECRET"),
        authorization_params={
          "scope": "openid profile email", # Necesario para obtener información del perfil del usuario
        }
    )

    # Instanciar el AuthClient
    auth_client = AuthClient(config)

    # Asociar al estado de la aplicación FastAPI
    app.state.config = config
    app.state.auth_client = auth_client

    # Registrar rutas de autenticación
    register_auth_routes(router, config)
    app.include_router(router)


    @app.get("/", response_class=HTMLResponse)
    async def home(request: Request, response: Response):
        """Home page with login/logout buttons"""
        store_options = {"request": request, "response": response}
        session = await auth_client.client.get_session(store_options=store_options)

        if session:
            user = await auth_client.client.get_user(store_options=store_options)
            return f"""
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {{
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }}
                    .container {{
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }}
                    .logo {{
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }}
                    h1 {{
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }}
                    .success {{
                        font-size: 1.5rem;
                        color: #68d391;
                        font-weight: 600;
                        margin: 1.5rem 0;
                    }}
                    .profile {{
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2rem;
                        margin: 2rem 0;
                    }}
                    .profile-image {{
                        width: 110px;
                        height: 110px;
                        border-radius: 50%;
                        border: 3px solid #63b3ed;
                        margin-bottom: 1rem;
                    }}
                    .profile-name {{
                        font-size: 2rem;
                        font-weight: 600;
                        color: #f7fafc;
                        margin-bottom: 0.5rem;
                    }}
                    .profile-email {{
                        font-size: 1.15rem;
                        color: #a0aec0;
                    }}
                    .button {{
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }}
                    .button.logout {{
                        background-color: #fc8181;
                        color: #1a1e27;
                    }}
                    .button.logout:hover {{
                        background-color: #e53e3e;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }}
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="success">✅ Successfully authenticated!</div>
                    <h2>Your Profile</h2>
                    <div class="profile">
                        <img src="{user.get('picture', '')}"
                             alt="{user.get('name', 'User')}" class="profile-image">
                        <div class="profile-name">{user.get('name', 'User')}</div>
                        <div class="profile-email">{user.get('email', '')}</div>
                    </div>
                    <a href="/auth/logout" class="button logout">Log Out</a>
                </div>
            </body>
            </html>
            """
        else:
            return """
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }
                    .container {
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }
                    .logo {
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }
                    h1 {
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }
                    .action-card {
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2.5rem;
                        margin-top: 2rem;
                    }
                    .action-text {
                        font-size: 1.25rem;
                        color: #cbd5e0;
                        margin-bottom: 1.8rem;
                    }
                    .button {
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }
                    .button.login {
                        background-color: #63b3ed;
                        color: #1a1e27;
                    }
                    .button.login:hover {
                        background-color: #4299e1;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="action-card">
                        <p class="action-text">Get started by signing in to your account</p>
                        <a href="/auth/login" class="button login">Log In</a>
                    </div>
                </div>
            </body>
            </html>
            """


    @app.get("/profile")
    async def profile(
        request: Request,
        response: Response,
        session=Depends(auth_client.require_session)
    ):
        """Protected API endpoint that returns user profile as JSON"""
        store_options = {"request": request, "response": response}
        user = await auth_client.client.get_user(store_options=store_options)

        return {
            "message": "Your Profile",
            "user": user,
            "session_details": session
        }


    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=3000)
    ```

    Esto crea:

    * Una página de inicio (`/`) que muestra un botón de inicio de sesión cuando no se ha iniciado sesión, o el perfil del usuario cuando se ha iniciado sesión
    * Un endpoint protegido de la API (`/profile`) que devuelve datos de usuario en formato JSON y requiere autenticación
    * Estilos completos para una experiencia de usuario pulida
  </Step>

  <Step title="Ejecuta tu aplicación" stepNumber={6}>
    ```shellscript theme={null}
    uvicorn main:app --reload --port 3000
    ```

    Como alternativa, si agregaste el bloque `if __name__ == "__main__"` a tu `main.py`:

    ```shellscript theme={null}
    python main.py
    ```
  </Step>
</Steps>

<Check>
  **Punto de control**

  Ahora deberías tener una página de inicio de sesión de Auth0 totalmente funcional ejecutándose en tu [localhost](http://localhost:3000/).
</Check>

***

<div id="advanced-usage">
  ## Uso avanzado
</div>

<Accordion title="Protección de rutas de API con dependencias personalizadas">
  Cree dependencias personalizadas de FastAPI para el control de acceso basado en roles:

  ```python theme={null}
  from fastapi import Depends, HTTPException, status
  from typing import List

  async def require_roles(required_roles: List[str]):
      """Factoría de dependencias para control de acceso basado en roles"""
      async def check_roles(
          request: Request,
          response: Response,
          session=Depends(auth_client.require_session)
      ):
          store_options = {"request": request, "response": response}
          user = await auth_client.client.get_user(store_options=store_options)

          user_roles = user.get("app_metadata", {}).get("roles", [])

          if not any(role in user_roles for role in required_roles):
              raise HTTPException(
                  status_code=status.HTTP_403_FORBIDDEN,
                  detail=f"Roles requeridos: {', '.join(required_roles)}"
              )

          return session

      return check_roles

  # Uso en rutas
  @app.get("/admin/dashboard")
  async def admin_dashboard(
      session=Depends(require_roles(["admin", "superadmin"]))
  ):
      return {"message": "Acceso concedido al panel de administración"}

  @app.delete("/admin/users/{user_id}")
  async def delete_user(
      user_id: str,
      session=Depends(require_roles(["admin"]))
  ):
      return {"message": f"Usuario {user_id} eliminado"}
  ```
</Accordion>

<Accordion title="Llamada a APIs protegidas con tokens de acceso">
  Configure el SDK para solicitar tokens de acceso para su API y utilizarlos en llamadas a servicios posteriores:

  ```python theme={null}
  from auth0_fastapi.config import Auth0Config
  import httpx

  # Configurar Auth0 con la audiencia de la API
  config = Auth0Config(
      domain=os.getenv("AUTH0_DOMAIN"),
      client_id=os.getenv("AUTH0_CLIENT_ID"),
      client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
      app_base_url=os.getenv("APP_BASE_URL"),
      secret=os.getenv("SESSION_SECRET"),
      audience="https://api.example.com",  # Su identificador de API
      authorization_params={
          "scope": "openid profile email read:data write:data",
      },
  )

  @app.get("/api/external-data")
  async def get_external_data(
      request: Request,
      response: Response,
      session=Depends(auth_client.require_session)
  ):
      """Llama a una API externa con el token de acceso del usuario"""
      # Obtener el token de acceso de la sesión
      access_token = session.get("access_token")

      if not access_token:
          raise HTTPException(
              status_code=status.HTTP_401_UNAUTHORIZED,
              detail="No hay ningún token de acceso disponible"
          )

      # Realizar una llamada autenticada a la API
      async with httpx.AsyncClient() as client:
          api_response = await client.get(
              "https://api.example.com/data",
              headers={"Authorization": f"Bearer {access_token}"}
          )

          if api_response.status_code != 200:
              raise HTTPException(
                  status_code=api_response.status_code,
                  detail="Error al llamar a la API externa"
              )

      return {"data": api_response.json()}
  ```
</Accordion>

<Accordion title="Uso de Redis para el almacenamiento de sesiones con estado">
  Escale su aplicación almacenando las sesiones en Redis en lugar de cookies cifradas:

  ```python theme={null}
  from auth0_fastapi.stores.stateful_state_store import StatefulStateStore
  from redis import asyncio as aioredis

  # Crear cliente de Redis
  redis = await aioredis.from_url(
      "redis://localhost:6379",
      encoding="utf-8",
      decode_responses=True
  )

  # Crear almacén con estado
  state_store = StatefulStateStore(
      secret=os.getenv("SESSION_SECRET"),
      store=redis,
      cookie_name="_session_id",
      expiration=86400,  # 1 día en segundos
  )

  # Pasar a AuthClient
  auth_client = AuthClient(config, state_store=state_store)
  ```

  Ventajas de las sesiones con estado:

  * **Sin límites de tamaño para las cookies** - Almacene datos de sesión sin límite
  * **Invalidación inmediata** - Elimine sesiones del lado del servidor
  * **Compatibilidad con cierre de sesión por canal de retorno** - Gestione eventos de cierre de sesión desde Auth0
  * **Mejor para sistemas distribuidos** - Comparta sesiones entre varios servidores
</Accordion>

***

<div id="troubleshooting">
  ## Solución de problemas
</div>

<Accordion title="Las sesiones no persisten / A los usuarios se les cierra la sesión repetidamente">
  **Problema**: Los usuarios inician sesión, pero las sesiones no persisten entre solicitudes.

  **Posibles causas y soluciones**:

  1. **Falta SessionMiddleware**

     Asegúrate de haber agregado SessionMiddleware a tu aplicación:

     ```python theme={null}
     from starlette.middleware.sessions import SessionMiddleware

     app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))
     ```

  2. **HTTP en producción con cookies seguras**

     Las cookies seguras requieren HTTPS. Si estás haciendo pruebas localmente con HTTP, puedes desactivar temporalmente las cookies seguras (no se recomienda en producción):

     ```python theme={null}
     from auth0_fastapi.stores.stateless_state_store import StatelessStateStore

     state_store = StatelessStateStore(
         secret=config.secret,
         cookie_name="_a0_session",
         expiration=config.session_expiration
     )
     # ¡Solo para desarrollo!
     state_store.cookie_options["secure"] = False

     auth_client = AuthClient(config, state_store=state_store)
     ```

  3. **SESSION\_SECRET débil o ausente**

     Genera un secreto robusto:

     ```shellscript theme={null}
     openssl rand -hex 64
     ```
</Accordion>

<Accordion title="Error de Auth0: Callback URL mismatch">
  **Problema**: Después de hacer clic en "Log In", Auth0 muestra este error: "Callback URL mismatch"

  **Causa**: La URL de callback no está registrada en la configuración de tu aplicación de Auth0.

  **Solución**:

  1. Ve a [Auth0 Dashboard](https://manage.auth0.com/) → Applications → Your App → Settings
  2. Agrega tu URL de callback a **Allowed Callback URLs**:
     ```
     http://localhost:3000/auth/callback
     ```
  3. En producción, agrega tu URL de producción:
     ```
     https://yourdomain.com/auth/callback
     ```
  4. Haz clic en **Save Changes**

  **Nota**: La URL debe coincidir exactamente, incluido el protocolo (http/https) y el número de puerto.
</Accordion>

<Accordion title="ImportError o problemas con async/await">
  **Problema**: Errores relacionados con funciones asíncronas o bucles de eventos.

  **Causa**: FastAPI es un framework asíncrono y todos los métodos del SDK deben esperarse con await.

  **Solución**: Asegúrate de que todas las funciones de ruta sean async y de que los métodos del SDK usen await correctamente:

  ```python theme={null}
  # ✅ Correcto
  @app.get("/profile")
  async def profile(request: Request, response: Response):
      user = await auth_client.client.get_user(
          store_options={"request": request, "response": response}
      )
      return {"user": user}

  # ❌ Incorrecto - falta async
  @app.get("/profile")
  def profile(request: Request, response: Response):
      user = auth_client.client.get_user(...)  # Esto fallará
      return {"user": user}

  # ❌ Incorrecto - falta await
  @app.get("/profile")
  async def profile(request: Request, response: Response):
      user = auth_client.client.get_user(...)  # Devuelve una corrutina, no datos
      return {"user": user}
  ```
</Accordion>

<Accordion title="HTTPS obligatorio en producción">
  **Problema**: Las sesiones funcionan localmente, pero no en producción.

  **Causa**: Las cookies seguras requieren HTTPS en producción. La marca `secure=True` evita que las cookies se envíen a través de conexiones HTTP sin cifrar.

  **Solución**:

  1. **Configura HTTPS** en tu servidor de producción usando:
     * certificados de Let's Encrypt
     * SSL/TLS del proveedor de nube (AWS ALB, Cloudflare, etc.)
     * proxy inverso (Nginx, Caddy, Traefik)

  2. **Actualiza las URL de tu aplicación de Auth0** para usar HTTPS:
     ```
     https://yourdomain.com/auth/callback
     https://yourdomain.com
     ```

  3. **Asegúrate de que APP\_BASE\_URL use HTTPS**:
     ```
     APP_BASE_URL=https://yourdomain.com
     ```
</Accordion>

Para ver funciones más avanzadas y opciones de configuración, consulta la [documentación del SDK de Auth0 FastAPI](https://github.com/auth0/auth0-fastapi/blob/main/README.md).
