Steg 1 — Registrera er publika nyckel (engångsinställning)
Generera ett 4096-bitars RSA-nyckelpar och dela den publika nyckeln med Zonos. Detta görs en gång under onboardingen.
Generera nyckelparet
# Generate private keyopenssl genrsa -out private_key.pem 4096 # Extract public keyopenssl rsa - private_key.pem -pubout -out public_key.pemDela public_key.pem med Zonos. Lagra private_key.pem i en dedikerad hemlighetshanterare (AWS Secrets Manager, HashiCorp Vault, etc.) — aldrig i källkodshantering eller miljövariabler.
Zonos registrerar er nyckel och returnerar ert organisations-ID, som blir iss-claimet i alla JWT-assertions.
Steg 2 — Bygg en JWT-assertion
Signera en JWT med RS256 med hjälp av er privata nyckel. Assertionen gäller för ett enda tokenutbyte — håll giltighetsfönstret kort (60–300 sekunder).
Obligatoriska claims
| Claim↕ | Värde↕ |
|---|---|
iss | Ert Zonos-organisations-ID (t.ex. "org_abc123") |
sub | Identifierar den anropande tjänsten (t.ex. "checkout-service") |
aud | Måste vara exakt "zonos-auth" |
exp | Unix-tidsstämpel; 60–300 sekunder från iat |
iat | Unix-tidsstämpel för utfärdande |
jti | Unikt UUID per assertion (möjliggör replay-detektering) |
JWT-huvudet måste ange "alg": "RS256" och "typ": "JWT".
Kodexempel
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",)Steg 3 — Byt assertionen mot en åtkomsttoken
Skicka den signerade JWT:n till Zonos token-endpoint för att få en kortlivad Bearer-token.
Endpoint
POST https://auth.zonos.com/oauth/token
Content-Type: application/json
application/x-www-form-urlencoded accepteras också.
Fält i förfrågan
| Fält↕ | Obligatoriskt↕ | Värde↕ |
|---|---|---|
grant_type | Ja | "urn:ietf:params:oauth:grant-type:jwt-bearer" |
assertion | Ja | Er signerade JWT (kompakt serialisering) |
Förfrågan och svar
{ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}| Svarsfält↕ | Beskrivning↕ |
|---|---|
access_token | Bearer-token för alla efterföljande API-förfrågningar |
token_type | Alltid "Bearer" |
expires_in | Sekunder tills token upphör (standard: 300) |
scope | Blankstegsavgränsade behörigheter som tilldelats denna token |
Fullständiga kodexempel
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"]Steg 4 — Anropa Zonos API:er med åtkomsttoken
Inkludera åtkomsttoken som en Bearer-token i Authorization-huvudet i varje Zonos API-förfrågan.
Exempelförfrågan
curl -X POST https://api.zonos.com/graphql \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "query": "{ ... }" }'Tokens livscykel och cachning
Åtkomsttokens upphör att gälla efter 5 minuter som standard. Cacha token och förnya den proaktivt — begär inte en ny token vid varje API-anrop. Varje förnyelse kräver en nysignerad JWT-assertion.
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"]Felreferens
Alla fel följer OAuth 2.0:s format för felsvar (RFC 6749 §5.2):
{ "error": "invalid_grant", "error_description": "JWT assertion has expired"}| HTTP-status↕ | error↕ | Orsak↕ |
|---|---|---|
400 | unsupported_grant_type | grant_type var inte urn:ietf:params:oauth:grant-type:jwt-bearer |
400 | invalid_request | Saknat eller felaktigt formaterat fält |
401 | invalid_grant | Ogiltig signatur, utgången assertion, okänd organisation eller oregistrerad nyckel |
500 | server_error | Internt fel — kontakta Zonos support om problemet kvarstår |
Vanliga orsaker till invalid_grant:
expligger i det förflutna — säkerställ att er systemklocka är NTP-synkroniseradaudär inte exakt"zonos-auth"issmatchar inte ert registrerade organisations-ID- Den publika nyckeln har roterats men ännu inte uppdaterats hos Zonos
Bästa praxis för säkerhet
- Skydda er privata nyckel. Lagra den i en dedikerad hemlighetshanterare — aldrig i källkodshantering, miljövariabler eller loggar.
- Håll assertions kortlivade. 60–300 sekunder är standard; det finns ingen anledning att utfärda längre sådana.
- Inkludera
jti. Ett unikt värde per assertion möjliggör serversidans replay-detektering. - Rotera nyckelpar regelbundet. Registrera en ny publik nyckel hos Zonos innan ni återkallar den gamla för att undvika driftstopp.
- Logga aldrig värden för
access_tokenellerassertion. Behandla båda som autentiseringsuppgifter.
OAuth 2.0-autentisering
Autentisera era backend-tjänster med Zonos med hjälp av asymmetrisk nyckelkryptering — inga delade hemligheter.
Zonos stöder autentisering mellan maskiner via OAuth 2.0 JWT Bearer Token Grant (RFC 7523). Er tjänst signerar en kortlivad JWT med er privata RSA-nyckel; Zonos verifierar den med hjälp av er registrerade publika nyckel och returnerar en Bearer-token knuten till er organisation.
Sammanfattning av flödet:
Authorization: Bearer <token>i varje API-förfrågan.