メインコンテンツへスキップ

AI プロンプト

AIを使ってAuth0を統合していますか? このプロンプトをCursor、Windsurf、Copilot、Claude Code、またはお気に入りのAI搭載IDEに追加して、開発を効率化しましょう。
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 を無効にしてください(非推奨)
前提条件: 始める前に、次のものがインストールされていることを確認してください。
  • Python 3.9 以降 (推奨: 3.11 以上)
  • pip 21+ または Poetry 1.2+
  • OpenSSL - セッションシークレットの生成に必要
FastAPI のバージョン互換性: このクイックスタートには FastAPI 0.115.11+ および Pydantic 2.12.5+ が必要です。

はじめに

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

新規プロジェクトを作成する

プロジェクト用の新しいディレクトリを作成し、仮想環境をセットアップします。
mkdir auth0-fastapi-app && cd auth0-fastapi-app
仮想環境を作成し、有効化します:
python -m venv venv
source venv/bin/activate  # Windowsの場合: venv\Scripts\activate
2

Auth0 FastAPI SDKをインストールする

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

Auth0アプリを設定する

次に、Auth0テナントで新しいアプリを作成し、プロジェクトに環境変数を追加します。CLIコマンドを実行して自動的に行う方法と、Dashboardから手動で行う方法のいずれかを選択できます。
Auth0 アプリを作成して .env ファイルを生成するには、プロジェクトのルートディレクトリで次のシェルコマンドを実行します。
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
4

Auth0 FastAPI SDKを設定する

プロジェクトのルートディレクトリに main.py ファイルを作成し、次のコードを追加してください。
main.py
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)
SESSION_SECRET はセッションクッキーの暗号化に使用されるため、暗号学的に安全である必要があります。十分に強力なシークレット (最低 32 バイト) がないと、アプリケーションのセッションが侵害されるおそれがあります。openssl rand -hex 64 を使用して安全なシークレットを生成し、バージョン管理にコミットしないでください。SessionMiddleware は、SDK を使用する前に追加する必要があります。これがないと、FastAPI はクッキーを読み書きできず、すべての認証の試行が何のエラーも表示されないまま失敗します。本番環境での HTTPS は、安全なクッキー (secure=True) に必須です。HTTPS がないと、セッションクッキーはブラウザーから送信されず、ユーザーは各リクエストのたびにログアウトされ続けます。
5

ルートを作成し、ユーザープロフィールを表示する

次のルートを main.py ファイルに追加して、ホームページと保護されたプロファイルページを作成します。
main.py
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)
  • 洗練されたユーザー体験を実現する充実したスタイリング
6

アプリを実行する

uvicorn main:app --reload --port 3000
また、main.pyif __name__ == "__main__" ブロックを追加した場合は、次のように実行します。
python main.py
チェックポイントこれで、Auth0 のログインページが localhost で正常に動作するようになっているはずです。

高度な使用方法

ロールベースアクセス制御用のカスタム FastAPI 依存関係を作成します。
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"}
API 用のアクセストークンをリクエストするよう SDK を設定し、後続の呼び出しで使用します。
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()}
暗号化されたクッキーではなく Redis にセッションを保存して、アプリケーションをスケールさせます。
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 からのログアウトイベントを処理
  • 分散システムに適している - 複数のサーバー間でセッションを共有

トラブルシューティング

問題: 「Log In」をクリックすると、Auth0 に「Callback URL mismatch」というエラーが表示されます原因: callback URL が Auth0 アプリケーションの設定に登録されていません。解決策:
  1. Auth0 Dashboard → 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) やポート番号を含めて完全に一致している必要があります。
問題: async 関数やイベントループに関連するエラーが発生します。原因: FastAPI は async フレームワークであり、すべての SDK メソッドは await する必要があります。解決策: すべてのルート関数が async であり、SDK メソッドが正しく await されていることを確認してください:
# ✅ 正しい
@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}
問題: ローカルではセッションが機能するのに、本番環境では機能しません。原因: 本番環境で 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
    
より高度な機能や設定オプションについては、Auth0 FastAPI SDK documentation を参照してください。