Aller au contenu

sdk/python

SDK serveur Python asynchrone pour la vérification JWT sans réseau,l'authentification des requêtes et la validation des signatures webhook.

Afficher en Markdown

Statut

Implémenté et vérifié localement. La vérification aller-retour avec unvrai IdP (récupération JWKS, signature/vérification de jeton contre uneinstance XID active) n’a pas encore été effectuée et doit être complétéeavant toute utilisation en production.

Statut du registre : UNPUBLISHED. Installez ce SDK uniquement depuis un checkout du code source du dépôt ; n’utilisez pas de registre de paquets externe.

L’authentification des requêtes accepte uniquement Bearer par défaut. Un cookie JWT détenu par l’application n’est lu que lorsque son nom exact est configuré. Le cookie Core opaque __Host-xid.rt.* n’est jamais recherché ni vérifié localement ; échangez-le en transférant le header Cookie complet vers le POST /v1/sessions/token de même origine exacte, avec les redirections désactivées, et n’acceptez qu’une réponse contenant uniquement le champ token.

Installer

pip install "xid @ git+https://github.com/StringKe/xid#subdirectory=sdk/python"

Démarrage rapide

Construisez un seul XidClient au démarrage et réutilisez-le. Leclient met le JWKS en cache en interne.

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 (Bearer-only by default)
status = await client.authenticate_request(headers=dict(request.headers))
if not status.authenticated:
    raise Unauthorized()
user_id = status.claims.sub

# Explicit same-origin Core session -> JWT exchange
token = await client.exchange_session_token(
    incoming_request_url="https://app.example.com/account",
    cookie_header=request.headers["cookie"],
)

Vérifier le webhook

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

Intégration 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}

Options XidClient

Paramètre Défaut Description
issuer requis URL d’émetteur XID
audience None Revendication aud attendue ; None ignore la validation
jwks_ttl 3600 TTL du cache JWKS en mémoire en secondes
http_timeout 10.0 Délai de récupération JWKS en secondes
cookie_name disabled Nom du cookie JWT détenu par l’application ; désactivé sauf configuration explicite
leeway 0 Tolérance au décalage d’horloge en secondes

API principale

Méthode Description
await client.verify_token(token) Vérifier la chaîne JWT ; lève TokenVerificationError en casd’échec.
await client.authenticate_request(headers, cookies) Extraire et vérifier le jeton depuis les en-têtes/cookies. RetourneAuthStatus ; ne lève pas d’exception.
client.verify_webhook(payload, headers, secret) Synchrone. Valide le HMAC-SHA256 svix + fenêtre de relecture de 5 minutes.Lève WebhookVerificationError en cas d’échec.
await client.aclose() Libérer les ressources du client HTTP sous-jacent.

Notes de plateforme

  • Asynchrone par défaut. Les appelants synchrones (Django/Flask) peuventutiliser asyncio.run().
  • Dépend de pyjwt[crypto] >=2.8 et httpx >=0.27. Python 3.10+requis.
  • Les déploiements multi-worker ne partagent pas de cache JWKS entre lesprocessus. Un cache partagé (Redis) est une amélioration prévue.
Navigation

Saisissez votre recherche...

Utilisez les touches fléchées pour naviguerAppuyez sur Entrée pour sélectionnerAppuyez sur Échap pour fermer