Ir para o conteúdo

sdk/python

SDK de servidor Python assíncrono para verificação JWT sem rede,autenticação de requisições e validação de assinatura de webhook.

Ver como Markdown

Estado

Implementado e verificado localmente. A verificação de ida e voltacom um IdP real (busca de JWKS, assinatura/verificação de tokencontra uma instância XID ativa) ainda não foi realizada e deve serconcluída antes do uso em produção.

Status do registry: UNPUBLISHED. Instale este SDK somente a partir do checkout do código-fonte do repositório; não use um registry de pacotes externo.

A autenticação de requisições aceita somente Bearer por padrão. Um cookie JWT pertencente ao aplicativo só é lido quando seu nome exato é configurado. O cookie opaco do Core __Host-xid.rt.* nunca é pesquisado nem verificado localmente; troque-o encaminhando o header Cookie completo para o POST /v1/sessions/token da mesma origem exata, com redirects desativados, e aceite somente uma resposta que contenha apenas o campo token.

Instalar

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

Início rápido

Construa um XidClient na inicialização e reutilize-o. Ocliente faz cache do JWKS internamente.

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"],
)

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

Integração com 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}

Opções do XidClient

Parâmetro Padrão Descrição
issuer obrigatório URL do emissor XID
audience None Claim aud esperado; None ignora a validação
jwks_ttl 3600 TTL do cache em memória do JWKS em segundos
http_timeout 10.0 Timeout de busca do JWKS em segundos
cookie_name disabled Nome do cookie JWT pertencente ao aplicativo; desativado salvo configuração explícita
leeway 0 Tolerância de desvio de relógio em segundos

API principal

Método Descrição
await client.verify_token(token) Verifica string JWT; lança TokenVerificationError em caso defalha.
await client.authenticate_request(headers, cookies) Extrai e verifica o token de headers/cookies. RetornaAuthStatus; não lança exceções.
client.verify_webhook(payload, headers, secret) Síncrono. Valida HMAC-SHA256 svix + janela de replay de 5 minutos.Lança WebhookVerificationError em caso de falha.
await client.aclose() Libera os recursos do cliente HTTP subjacente.

Notas da plataforma

  • Prioridade assíncrona. Chamadores síncronos (Django/Flask) podemenvolver com asyncio.run().
  • Depende de pyjwt[crypto] >=2.8 e httpx >=0.27. Python3.10+ obrigatório.
  • Implantações com múltiplos workers não compartilham cache JWKS entreprocessos. Um cache compartilhado (Redis) é uma melhoria planejada.
Navegação

Digite para pesquisar...

Use as teclas de seta para navegarPressione Enter para selecionarPressione Escape para fechar