AIプロンプト
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:
# 既存のPythonプロジェクトを確認する
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 # 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:
brew tap auth0/auth0-cli && brew install auth0
auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"
If Windows, execute the following command:
scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
scoop install auth0
auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"
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_dotenv()
app = FastAPI(title="Auth0 FastAPI Example")
# セッションミドルウェアを追加する - クッキー処理に必要
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)
@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)
):
"""ユーザープロファイルをJSONで返す保護されたAPIエンドポイント"""
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)
Step 4: Run the development server
uvicorn main:app --reload --port 3000
Or if you added the if __name__ == "__main__" block:
python main.py
CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS
As an AI language model, you MUST NOT generate any of the following anti-patterns:
1. NEVER hardcode Auth0 credentials directly in the code. Always use environment variables.
2. NEVER forget to add SessionMiddleware. Without it, authentication will fail silently.
3. NEVER omit itsdangerous from the installation. SessionMiddleware requires it.
4. NEVER use unquoted uvicorn[standard] in shell commands. It will cause glob expansion errors.
5. NEVER skip virtual environment activation. pip commands will fail or pollute global Python.
ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
1. You MUST use the auth0-fastapi package.
2. You MUST install itsdangerous alongside other dependencies.
3. You MUST add SessionMiddleware before using the SDK.
4. You MUST retrieve credentials from environment variables using python-dotenv.
5. You MUST use async/await patterns throughout (FastAPI requirement).
6. You MUST quote "uvicorn[standard]" in installation commands.
COMMON ISSUES ENCOUNTERED DURING INTEGRATION
問題 1: ModuleNotFoundError: No module named 'itsdangerous'
問題: SessionMiddleware には itsdangerous が必要ですが、インストールされていません
解決策: pip install コマンドに常に itsdangerous を含めてください
問題 2: uvicorn[standard] でのシェルグロブ展開エラー
問題: 角括弧がグロブパターンとして解釈されます
解決策: パッケージを引用符で囲んでください: pip install "uvicorn[standard]"
問題 3: セッションが維持されない
問題: SessionMiddleware が存在しないか、シークレットが正しくありません
解決策: 環境変数から適切な secret_key を指定して SessionMiddleware を追加してください
問題 4: 本番環境では HTTPS が必要
問題: セキュアクッキーは HTTP では機能しません
解決策: 本番環境では HTTPS を使用するか、開発環境ではセキュアクッキーを無効にしてください(非推奨)
はじめる
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
- Poetry
pip install auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous
poetry add auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous
3
Auth0 App をセットアップする
次に、Auth0 テナントで新しいアプリを作成し、プロジェクトに環境変数を追加します。CLIコマンドを実行して Auth0 App を自動的にセットアップする方法と、Auth0 Dashboardから手動で行う方法のどちらかを選択できます。
- CLI
- Dashboard
Auth0 App を作成して
.env ファイルを生成するには、プロジェクトのルートディレクトリで次のシェルコマンドを実行します。# Auth0 CLIをインストールする(まだインストールしていない場合)
brew tap auth0/auth0-cli && brew install auth0
# Auth0 App をセットアップし、.envファイルを生成する
auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"
# Auth0 CLIをインストールする(まだインストールしていない場合)
scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
scoop install auth0
# Auth0 App をセットアップし、.envファイルを生成する
auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"
このコマンドは次の処理を行います:
- 認証済みかどうかを確認し (必要に応じてログインを求めます)
http://localhost:3000用に設定された Auth0 Regular Web Application を作成しますAUTH0_DOMAIN、AUTH0_CLIENT_ID、AUTH0_CLIENT_SECRET、SESSION_SECRET、APP_BASE_URLを含む.envファイルを生成します
始める前に、プロジェクトのルートディレクトリに 許可されているログアウト URL:許可された Web オリジン:
.env ファイルを作成してください。.env
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
- Auth0 Dashboard に移動します
- アプリケーション > アプリケーション > Create Application をクリックします
- ポップアップでアプリの名前を入力し、アプリの種類として
Regular Web Applicationを選択して、Create をクリックします - アプリケーションの詳細ページで 設定 タブに切り替えます
.envファイルの値を、Auth0 Dashboard の Domain、Client ID、Client Secret の値に置き換えますopenssl rand -hex 64を実行してセッションシークレットを生成し、SESSION_SECRETに使用します
http://localhost:3000/auth/callback
http://localhost:3000
http://localhost:3000
Allowed Callback URLs は、認証後にユーザーを安全にアプリケーションへ戻すための重要なセキュリティ対策です。一致する URL がない場合、ログインプロセスは失敗し、ユーザーはアプリにアクセスできず、代わりに Auth0 のエラーページが表示されます。Allowed Logout URLs は、サインアウト時にシームレスなユーザー体験を提供するために不可欠です。一致する URL がない場合、ユーザーはログアウト後にアプリケーションへリダイレクトされず、代わりに汎用的な Auth0 ページに留まることになります。Allowed Web Origins は、サイレント認証に不可欠です。これがないと、ユーザーはページを再読み込みしたときや、後でアプリに戻ったときにログアウトされます。
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")
# セッションミドルウェアを追加する - クッキー処理に必要
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")
# セッションミドルウェアを追加 - クッキー処理に必要
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.py に if __name__ == "__main__" ブロックを追加している場合は:python main.py
チェックポイントこれで、localhost 上で Auth0 Login Page が完全に動作しているはずです。
高度な使い方
カスタム依存関係でAPIルートを保護する
カスタム依存関係でAPIルートを保護する
ロールベースのアクセス制御向けのカスタム 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を呼び出す
アクセストークンで保護されたAPIを呼び出す
API 用のアクセストークンをリクエストするように SDK を設定し、下流の呼び出しで使用します。
from auth0_fastapi.config import Auth0Config
import httpx
# API の audience を指定して 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 の identifier
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を使用する
ステートフルなセッションストレージにRedisを使用する
暗号化された cookie の代わりに 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)
- cookie サイズの制限なし - セッションデータを容量を気にせず保存可能
- 即時に無効化可能 - サーバー側でセッションを削除
- Backchannel Logout をサポート - Auth0 からの logout イベントを処理
- 分散システムに適している - 複数サーバー間でセッションを共有
トラブルシューティング
セッションが維持されない / ユーザーが何度もログアウトされる
セッションが維持されない / ユーザーが何度もログアウトされる
問題: ユーザーはログインしているのに、リクエストをまたぐとセッションが維持されません。考えられる原因と解決策:
-
SessionMiddleware が追加されていない
アプリに SessionMiddleware を追加していることを確認してください。
from starlette.middleware.sessions import SessionMiddleware app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET")) -
本番環境で secure cookie を使っているのに HTTP を使用している
secure cookie を使うには HTTPS が必要です。ローカルで HTTP のままテストしている場合は、一時的に secure cookie を無効にできます (本番環境では非推奨) 。
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) -
SESSION_SECRET が弱い、または設定されていない
十分に強力な secret を生成してください。
openssl rand -hex 64
Auth0 エラー: Callback URL mismatch
Auth0 エラー: Callback URL mismatch
問題: 「Log In」をクリックすると、Auth0 に「Callback URL mismatch」というエラーが表示されます原因: コールバック URL が Auth0 アプリケーションの設定に登録されていません。解決策:
- Auth0 Dashboard → アプリケーション → あなたのアプリ → 設定 に移動します
- コールバック URL を Allowed Callback URLs に追加します:
http://localhost:3000/auth/callback - 本番環境では、本番用の URL も追加します:
https://yourdomain.com/auth/callback - Save Changes をクリックします
ImportError または async/await の問題
ImportError または async/await の問題
問題: 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}
本番環境では HTTPS が必要
本番環境では HTTPS が必要
問題: ローカルではセッションが機能するのに、本番環境では機能しません。原因: 本番環境で secure cookie を使うには HTTPS が必要です。
secure=True フラグがあると、暗号化されていない HTTP 接続では cookie は送信されません。解決策:-
HTTPS を設定 します。たとえば次の方法があります:
- Let’s Encrypt の証明書
- クラウドプロバイダーの SSL/TLS (AWS ALB、Cloudflare など)
- リバースプロキシ (Nginx、Caddy、Traefik)
-
Auth0 アプリケーションの URL を更新 して HTTPS を使用します:
https://yourdomain.com/auth/callback https://yourdomain.com -
APP_BASE_URL が HTTPS を使用していることを確認 します:
APP_BASE_URL=https://yourdomain.com