状態
ローカルで実装および検証済み。実際の IdP ラウンドトリップ検証(JWKS 取得、実稼働 XID インスタンスに対するトークン署名/検証)はまだ実行されておらず、本番利用前に完了する必要があります。
インストール
pip install xidクイックスタート
起動時に XidClient を 1 つ作成して再利用します。クライアントは内部で JWKS をキャッシュします。
from xid import XidClient
client = XidClient(
issuer="https://xid.dev",
audience="https://api.yourapp.com", # optional
)
# Verify a token
claims = await client.verify_token("eyJ...")
print(claims.sub, claims.email, claims.scope)
# Authenticate a request
status = await client.authenticate_request(
headers=dict(request.headers),
cookies=dict(request.cookies),
)
if not status.authenticated:
raise Unauthorized()
user_id = status.claims.subwebhook を検証
from xid import WebhookVerificationError
try:
webhook = client.verify_webhook(
payload=request.body,
headers=dict(request.headers),
secret="whsec_xxx",
)
import json
event = json.loads(webhook.body)
except WebhookVerificationError as exc:
raise BadRequest(str(exc))FastAPI 統合
from fastapi import FastAPI, Depends, HTTPException, Request
from xid import XidClient, TokenClaims
app = FastAPI()
xid = XidClient(issuer="https://xid.dev")
@app.on_event("shutdown")
async def shutdown():
await xid.aclose()
async def require_auth(request: Request) -> TokenClaims:
status = await xid.authenticate_request(dict(request.headers))
if not status.authenticated:
raise HTTPException(status_code=401)
return status.claims
@app.get("/me")
async def me(claims: TokenClaims = Depends(require_auth)):
return {"sub": claims.sub, "email": claims.email}XidClient オプション
| パラメーター | デフォルト | 説明 |
|---|---|---|
issuer |
必須 | XID 発行者 URL |
audience |
None |
expected aud クレーム。None は検証をスキップします |
jwks_ttl |
3600 |
JWKS メモリ内キャッシュ TTL(秒) |
http_timeout |
10.0 |
JWKS 取得タイムアウト(秒) |
cookie_name |
__session |
セッショントークン取得用の Cookie キー |
leeway |
0 |
クロックスキュー許容値(秒) |
コア API
| 方式 | 説明 |
|---|---|
await client.verify_token(token) |
JWT 文字列を検証します。失敗時は TokenVerificationError を発生させます。 |
await client.authenticate_request(headers, cookies) |
ヘッダー/Cookie からトークンを取得して検証します。AuthStatus を返し、例外を発生させません。 |
client.verify_webhook(payload, headers, secret) |
同期実行。svix HMAC-SHA256 と 5 分間のリプレイウィンドウを検証します。失敗時は WebhookVerificationError を発生させます。 |
await client.aclose() |
基礎となる HTTP クライアントリソースを解放します。 |
プラットフォームの注意事項
- 非同期ファースト。同期呼び出し元(Django/Flask)は
asyncio.run()でラップできます。 pyjwt[crypto] >=2.8とhttpx >=0.27が必要です。Python 3.10+ が必要です。- マルチワーカーデプロイではプロセス間で JWKS キャッシュを共有しません。共有キャッシュ(Redis)は計画中の改善です。