Passo 1 — Registre sua chave pública (configuração única)
Gere um par de chaves RSA de 4096 bits e compartilhe a chave pública com Zonos. Isso é feito uma vez durante a integração.
Gere o par de chaves
# Generate private keyopenssl genrsa -out private_key.pem 4096 openssl rsa - private_key.pem -pubout -out public_key.pemCompartilharpublic_key.pemcom Zonos. Lojaprivate_key.pemem um gerenciador de segredos dedicado (AWS Secrets Manager, HashiCorp Vault, etc.) — nunca em controle de origem ou variáveis de ambiente.
Zonos registrará sua chave e retornará seuID da organização, que se torna oissreivindicação em todas as asserções JWT.
Passo 2 — Construa uma asserção JWT
Assine um JWT comRS256usando sua chave privada. A afirmação é válida para uma única troca de token – mantenha a janela de expiração curta (60–300 segundos).
Reivindicações obrigatórias
| Claim↕ | Value↕ |
|---|---|
iss | Your Zonos Organization ID (e.g. "org_abc123") |
sub | Identifies the calling service (e.g. "checkout-service") |
aud | Must be exactly "zonos-auth" |
exp | Carimbo de data/hora Unix; 60–300 segundos de iat |
iat | Unix timestamp of issuance |
jti | UUID exclusivo por asserção (permite detecção de repetição) |
O cabeçalho JWT deve especificar"alg": "RS256"e"typ": "JWT".
Exemplos de código
import jwt, uuid, time with open("private_key.pem") as f: private_key = f.read() now = int(time.time())assertion = jwt.encode( { "iss": "org_abc123", "sub": "checkout-service", "aud": "zonos-auth", "iat": now, "exp": now + 300, "jti": str(uuid.uuid4()), }, private_key, algorithm="RS256",)Passo 3 — Troque a afirmação por um token de acesso
Envie o JWT assinado para o endpoint do token Zonos para receber um token Bearer de curta duração.
Ponto final
POST https://auth.zonos.com/oauth/token
Content-Type: application/json
application/x-www-form-urlencodedtambém é aceito.
Campos de solicitação
| Field↕ | Required↕ | Value↕ |
|---|---|---|
grant_type | Yes | "urn:ietf:params:oauth:grant-type:jwt-bearer" |
assertion | Yes | Your signed JWT (compact serialization) |
Solicitação e resposta
{ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}| Response field↕ | Description↕ |
|---|---|
access_token | Token de portador para todas as solicitações API subsequentes |
token_type | Always "Bearer" |
expires_in | Segundos até a expiração (padrão: 300) |
scope | Space-separated permissions granted to this token |
Exemplos de código completo
import requests response = requests.post( "https://auth.zonos.com/oauth/token", json={ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion, },)data = response.json()access_token = data ["access_token"]expires_in = data ["expires_in"]Passo 4 — Ligue para Zonos APIs com o token de acesso
Inclua o token de acesso como umBearerficha noAuthorizationcabeçalho em cada solicitação Zonos API.
Solicitação de exemplo
curl -X POST https://api.zonos.com/graphql \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "query": "{ ... }" }'Ciclo de vida e cache do token
Os tokens de acesso expiram em 5 minutos por padrão. Armazene o token em cache e atualize proativamente — não solicite um novo token em cada chamada API. Cada atualização requer uma declaração JWT recém-assinada.
import time, requests _cache = {"access_token": None, "expires_at": 0} def get_access_token(): if time.time() < _cache ["expires_at"] - 30: return _cache ["access_token"] assertion = build_jwt_assertion() data = requests.post( "https://auth.zonos.com/oauth/token", json={ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion, }, ).json() _cache ["access_token"] = data ["access_token"] _cache ["expires_at"] = time.time() + data ["expires_in"] return _cache ["access_token"]Referência de erro
Todos os erros seguem o formato de resposta de erro do OAuth 2.0 (RFC 6749 §5.2):
{ "error": "invalid_grant", "error_description": "JWT assertion has expired"}| HTTP Status↕ | error↕ | Cause↕ |
|---|---|---|
400 | unsupported_grant_type | grant_typenão foiurn:ietf:params:oauth:grant-type:jwt-bearer |
400 | invalid_request | Missing or malformed field |
401 | invalid_grant | Assinatura inválida, declaração expirada, organização desconhecida ou chave não registrada |
500 | server_error | Erro interno – entre em contato com o suporte Zonos se persistir |
Comuminvalid_grantcausas:
expestá no passado - certifique-se de que o relógio do seu sistema esteja sincronizado com NTPaudnão é exatamente"zonos-auth"issnão corresponde ao seu ID de organização registrado- A chave pública foi rotacionada, mas ainda não atualizada com Zonos
Melhores práticas de segurança
- **Proteja sua chave privada.**Armazene-o em um gerenciador de segredos dedicado — nunca em controle de origem, variáveis de ambiente ou logs.
- **Mantenha as afirmações de curta duração.**60–300 segundos é o padrão; não há razão para emitir outros mais longos.
- Incluir
jti. Um valor exclusivo por asserção permite a detecção de reprodução no lado do servidor. - **Gire os pares de chaves periodicamente.**Registre uma nova chave pública com Zonos antes de revogar a antiga para evitar tempo de inatividade.
- Nunca registre
access_tokenorassertionvalores. Trate ambos como credenciais.
Autenticação OAuth 2.0
Autentique seus serviços de back-end com Zonos usando criptografia de chave assimétrica — sem segredos compartilhados.
Zonos suporta autenticação máquina a máquina viaConcessão de token ao portador JWT OAuth 2.0 (RFC 7523). Seu serviço assina um JWT de curta duração com sua chave privada RSA; Zonos verifica usando sua chave pública registrada e retorna um token de portador com escopo para sua organização.
Resumo do fluxo:
Authorization: Bearer <token>em cada solicitação API.