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

> このガイドでは、Auth0 FastAPI SDK を使用して Python アプリケーションに Auth0 を統合し、認証を追加して、ユーザープロフィール情報を表示する方法を説明します。

# FastAPI アプリケーションにログインを追加する

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

<HowToSchema />

<Accordion title="AI プロンプト" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **AIを使ってAuth0を統合していますか？** このプロンプトをCursor、Windsurf、Copilot、Claude Code、またはお気に入りのAI搭載IDEに追加して、開発を効率化しましょう。

  ```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:

    # Pythonとpipがインストールされているかどうかを確認する
    python --version && pip --version

  Then examine the current directory:

    # Check for existing Python project
    if [ -f "main.py" ] || [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
      echo "Found existing Python project"
      ls -la
    else
      echo "No Python project found, will create new project"
    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

    # Load environment variables
    load_dotenv()

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

    # Add Session Middleware - required for cookie handling
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Create Auth0Config with your Auth0 credentials
    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"),
    )

    # Instantiate the AuthClient
    auth_client = AuthClient(config)

    # Attach to the FastAPI app state
    app.state.config = config
    app.state.auth_client = auth_client

    # Register authentication routes
    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)

  ステップ4：開発サーバーを起動する

    uvicorn main:app --reload --port 3000

  または、`if __name__ == "__main__"` ブロックを追加した場合：

    python main.py

  AIモデルへの重要な指示
  AIモデルとして、以下のアンチパターンを生成してはなりません：
  1.  Auth0の認証情報をコードに直接ハードコードしないこと。必ず環境変数を使用すること。
  2.  SessionMiddlewareの追加を忘れないこと。これがないと、認証がサイレントに失敗します。
  3.  インストール時にitsdangerousを省略しないこと。SessionMiddlewareはこれを必要とします。
  4.  シェルコマンドでuvicorn[standard]を引用符なしで使用しないこと。グロブ展開エラーが発生します。
  5.  仮想環境のアクティベーションをスキップしないこと。pipコマンドが失敗するか、グローバルPython環境を汚染します。

  AIコード生成の絶対要件
  1.  auth0-fastapiパッケージを使用すること。
  2.  他の依存関係と合わせてitsdangerousをインストールすること。
  3.  SDKを使用する前にSessionMiddlewareを追加すること。
  4.  python-dotenvを使用して環境変数から認証情報を取得すること。
  5.  全体を通じてasync/awaitパターンを使用すること（FastAPIの要件）。
  6.  インストールコマンドでは"uvicorn[standard]"を引用符で囲むこと。

  統合時によく発生する問題

  Issue 1: ModuleNotFoundError: No module named 'itsdangerous'
  問題: SessionMiddleware には itsdangerous が必要ですが、インストールされていません
  解決策: pip install コマンドには常に itsdangerous を含めてください

  Issue 2: uvicorn[standard] でシェルのグロブ展開エラーが発生する
  問題: 角括弧がグロブパターンとして解釈されます
  解決策: パッケージをクォートしてください: pip install "uvicorn[standard]"

  Issue 3: セッションが維持されない
  問題: SessionMiddleware が存在しないか、シークレットが正しくありません
  解決策: 環境変数から適切な secret_key を指定して SessionMiddleware を追加してください

  Issue 4: 本番環境では HTTPS が必要
  問題: セキュア cookie は HTTP では機能しません
  解決策: 本番環境では HTTPS を使用するか、開発環境ではセキュア cookie を無効にしてください（非推奨）
  ```
</Accordion>

<Note>
  **前提条件:** 始める前に、次のものがインストールされていることを確認してください。

  * **[Python](https://www.python.org/downloads/)** 3.9 以降 (推奨: 3.11 以上)
  * **[pip](https://pip.pypa.io/)** 21+ または **[Poetry](https://python-poetry.org/)** 1.2+
  * **[OpenSSL](https://www.openssl.org/)** - セッションシークレットの生成に必要

  **FastAPI のバージョン互換性:** このクイックスタートには **FastAPI 0.115.11+** および **Pydantic 2.12.5+** が必要です。
</Note>

<div id="get-started">
  ## はじめに
</div>

このクイックスタートでは、Python FastAPI Web アプリケーションに Auth0 認証を追加する方法を説明します。[Auth0 FastAPI SDK](https://github.com/auth0/auth0-fastapi) を使用して、ログイン、ログアウト、ユーザープロフィール機能を備えたセキュアな Web アプリケーションを構築します。

<Steps>
  <Step title="新規プロジェクトを作成する" stepNumber={1}>
    プロジェクト用の新しいディレクトリを作成し、仮想環境をセットアップします。

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

    仮想環境を作成し、有効化します:

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

  <Step title="Auth0 FastAPI SDKをインストールする" 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="Auth0アプリを設定する" stepNumber={3}>
    次に、Auth0テナントで新しいアプリを作成し、プロジェクトに環境変数を追加します。

    CLIコマンドを実行して自動的に行う方法と、Dashboardから手動で行う方法のいずれかを選択できます。

    <Tabs>
      <Tab title="CLI">
        Auth0 アプリを作成して `.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">
        始める前に、プロジェクトのルートディレクトリに `.env` ファイルを作成します。

        ```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. [Auth0 Dashboard](https://manage.auth0.com/dashboard/)を開きます
        2. **Applications** > **Applications** > **Create Application** をクリックします
        3. ポップアップでアプリの名前を入力し、アプリの種類として `Regular Web Application` を選択して、**Create** をクリックします
        4. Application Details ページの **Settings** タブに切り替えます
        5. `.env` ファイルの値を、Dashboard の **ドメイン**、**クライアントID**、**クライアントシークレット** の値で置き換えます
        6. `openssl rand -hex 64` を実行してセッションシークレットを生成し、`SESSION_SECRET` に使用します

        最後に、Application Details ページの **Settings** タブで、次の URL を設定します。

        **Allowed Callback URLs:**

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

        **Allowed Logout URLs:**

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

        **許可する Web オリジン:**

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

        <Info>
          **Allowed Callback URLs** は、認証後にユーザーを安全にアプリケーションへ戻すための重要なセキュリティ対策です。一致する URL がないとログインは失敗し、ユーザーはアプリにアクセスできず、代わりに Auth0 のエラーページが表示されます。

          **Allowed Logout URLs** は、サインアウト時にシームレスなユーザー体験を実現するうえで不可欠です。一致する URL がない場合、ユーザーはログアウト後にアプリケーションへリダイレクトされず、代わりに Auth0 の汎用ページにとどまります。

          **Allowed Web Origins** は、サイレント認証に不可欠です。これがないと、ユーザーはページを再読み込みしたときや、後でアプリに戻ったときにログアウトされます。
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Auth0 FastAPI SDKを設定する" stepNumber={4}>
    プロジェクトのルートディレクトリに `main.py` ファイルを作成し、次のコードを追加してください。

    ```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

    # 環境変数を読み込む
    load_dotenv()

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

    # セッションミドルウェアを追加する - cookieの処理に必要
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Auth0の認証情報を使用してAuth0Configを作成する
    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"),
    )

    # AuthClientをインスタンス化する
    auth_client = AuthClient(config)

    # FastAPIアプリのstateにアタッチする
    app.state.config = config
    app.state.auth_client = auth_client

    # 認証ルートを登録する
    register_auth_routes(router, config)
    app.include_router(router)
    ```

    <Info>
      **SESSION\_SECRET** はセッションクッキーの暗号化に使用されるため、暗号学的に安全である必要があります。十分に強力なシークレット (最低 32 バイト) がないと、アプリケーションのセッションが侵害されるおそれがあります。`openssl rand -hex 64` を使用して安全なシークレットを生成し、バージョン管理にコミットしないでください。

      **SessionMiddleware** は、SDK を使用する前に追加する必要があります。これがないと、FastAPI はクッキーを読み書きできず、すべての認証の試行が何のエラーも表示されないまま失敗します。

      **本番環境での HTTPS** は、安全なクッキー (`secure=True`) に必須です。HTTPS がないと、セッションクッキーはブラウザーから送信されず、ユーザーは各リクエストのたびにログアウトされ続けます。
    </Info>
  </Step>

  <Step title="ルートを作成し、ユーザープロフィールを表示する" stepNumber={5}>
    次のルートを `main.py` ファイルに追加して、ホームページと保護されたプロファイルページを作成します。

    ```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

    # 環境変数を読み込む
    load_dotenv()

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

    # セッションミドルウェアを追加する - cookie処理に必要
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Auth0の認証情報を使用してAuth0Configを作成する
    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", # ユーザープロフィール情報の取得に必要
        }
    )

    # AuthClientをインスタンス化する
    auth_client = AuthClient(config)

    # FastAPIアプリのstateにアタッチする
    app.state.config = config
    app.state.auth_client = auth_client

    # 認証ルートを登録する
    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)
    ```

    これにより以下が作成されます：

    * ログアウト時にはログインボタンが表示され、ログイン時にはユーザーのプロファイルが表示されるホームページ (`/`)
    * 認証が必要で、ユーザーデータを JSON として返す保護された API エンドポイント (`/profile`)
    * 洗練されたユーザー体験を実現する充実したスタイリング
  </Step>

  <Step title="アプリを実行する" stepNumber={6}>
    ```shellscript theme={null}
    uvicorn main:app --reload --port 3000
    ```

    また、`main.py` に `if __name__ == "__main__"` ブロックを追加した場合は、次のように実行します。

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

<Check>
  **チェックポイント**

  これで、Auth0 のログインページが [localhost](http://localhost:3000/) で正常に動作するようになっているはずです。
</Check>

***

<div id="advanced-usage">
  ## 高度な使用方法
</div>

<Accordion title="カスタム依存関係でAPIルートを保護する">
  ロールベースアクセス制御用のカスタム FastAPI 依存関係を作成します。

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

  async def require_roles(required_roles: List[str]):
      """ロールベースアクセス制御のための依存関係ファクトリ"""
      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"Required roles: {', '.join(required_roles)}"
              )

          return session

      return check_roles

  # ルートでの使用例
  @app.get("/admin/dashboard")
  async def admin_dashboard(
      session=Depends(require_roles(["admin", "superadmin"]))
  ):
      return {"message": "Admin dashboard access granted"}

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

<Accordion title="アクセストークンを使用した保護されたAPIの呼び出し">
  API 用のアクセストークンをリクエストするよう SDK を設定し、後続の呼び出しで使用します。

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

  # APIオーディエンスを指定して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"),
      secret=os.getenv("SESSION_SECRET"),
      audience="https://api.example.com",  # 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)
  ):
      """ユーザーのアクセストークンを使用して外部APIを呼び出す"""
      # セッションからアクセストークンを取得
      access_token = session.get("access_token")

      if not access_token:
          raise HTTPException(
              status_code=status.HTTP_401_UNAUTHORIZED,
              detail="No access token available"
          )

      # 認証付きの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="External API call failed"
              )

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

<Accordion title="ステートフルなセッションストレージにRedisを使用する">
  暗号化されたクッキーではなく Redis にセッションを保存して、アプリケーションをスケールさせます。

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

  # Redisクライアントを作成
  redis = await aioredis.from_url(
      "redis://localhost:6379",
      encoding="utf-8",
      decode_responses=True
  )

  # ステートフルストアを作成
  state_store = StatefulStateStore(
      secret=os.getenv("SESSION_SECRET"),
      store=redis,
      cookie_name="_session_id",
      expiration=86400,  # 秒単位で1日
  )

  # AuthClientに渡す
  auth_client = AuthClient(config, state_store=state_store)
  ```

  ステートフルなセッションの利点:

  * **クッキーサイズの制限なし** - 無制限のセッションデータを保存可能
  * **即時に無効化可能** - サーバー側でセッションを削除
  * **バックチャネルログアウトをサポート** - Auth0 からのログアウトイベントを処理
  * **分散システムに適している** - 複数のサーバー間でセッションを共有
</Accordion>

***

<div id="troubleshooting">
  ## トラブルシューティング
</div>

<Accordion title="セッションが維持されない / ユーザーが何度もログアウトされる">
  **問題**: ユーザーはログインできているものの、リクエストをまたぐとセッションが維持されません。

  **考えられる原因と解決策**:

  1. **SessionMiddleware が追加されていない**

     アプリに SessionMiddleware を追加していることを確認してください:

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

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

  2. **本番環境で HTTP を使用し、secure cookie が有効になっている**

     secure cookie を使用するには HTTPS が必要です。ローカルで HTTP を使ってテストしている場合は、一時的に secure cookie を無効にできます (本番環境では非推奨) :

     ```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
     )
     # 開発環境でのみ使用してください！
     state_store.cookie_options["secure"] = False

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

  3. **SESSION\_SECRET が弱い、または設定されていない**

     強力なシークレットを生成してください:

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

<Accordion title="Auth0 エラー: Callback URL の不一致">
  **問題**: 「Log In」をクリックすると、Auth0 に「Callback URL mismatch」というエラーが表示されます

  **原因**: callback URL が Auth0 アプリケーションの設定に登録されていません。

  **解決策**:

  1. [Auth0 Dashboard](https://manage.auth0.com/) → Applications → Your App → Settings に移動します
  2. callback URL を **Allowed Callback URLs** に追加します:
     ```
     http://localhost:3000/auth/callback
     ```
  3. 本番環境では、本番用の URL を追加します:
     ```
     https://yourdomain.com/auth/callback
     ```
  4. **Save Changes** をクリックします

  **注**: URL は、プロトコル (http/https) やポート番号を含めて完全に一致している必要があります。
</Accordion>

<Accordion title="ImportError または async/await の問題">
  **問題**: async 関数やイベントループに関連するエラーが発生します。

  **原因**: FastAPI は async フレームワークであり、すべての SDK メソッドは await する必要があります。

  **解決策**: すべてのルート関数が async であり、SDK メソッドが正しく await されていることを確認してください:

  ```python theme={null}
  # ✅ 正しい
  @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}

  # ❌ 誤り - async がない
  @app.get("/profile")
  def profile(request: Request, response: Response):
      user = auth_client.client.get_user(...)  # これは失敗します
      return {"user": user}

  # ❌ 誤り - await がない
  @app.get("/profile")
  async def profile(request: Request, response: Response):
      user = auth_client.client.get_user(...)  # データではなく coroutine を返します
      return {"user": user}
  ```
</Accordion>

<Accordion title="本番環境では HTTPS が必要">
  **問題**: ローカルではセッションが機能するのに、本番環境では機能しません。

  **原因**: 本番環境で secure cookie を使用するには HTTPS が必要です。`secure=True` フラグが設定されていると、暗号化されていない HTTP 接続では cookie が送信されません。

  **解決策**:

  1. **HTTPS を設定** します。使用できる方法の例:
     * Let's Encrypt の証明書
     * クラウドプロバイダーの SSL/TLS (AWS ALB、Cloudflare など)
     * リバースプロキシ (Nginx、Caddy、Traefik)

  2. **Auth0 アプリケーションの URL を更新** して HTTPS を使用します:
     ```
     https://yourdomain.com/auth/callback
     https://yourdomain.com
     ```

  3. **APP\_BASE\_URL で HTTPS を使用していることを確認** します:
     ```
     APP_BASE_URL=https://yourdomain.com
     ```
</Accordion>

より高度な機能や設定オプションについては、[Auth0 FastAPI SDK documentation](https://github.com/auth0/auth0-fastapi/blob/main/README.md) を参照してください。
