Krok 1 — Zarejestruj swój klucz publiczny (jednorazowa konfiguracja)
Wygeneruj parę kluczy RSA o rozmiarze 4096 bitów i udostępnij klucz publiczny w Zonos. Jest to wykonywane raz podczas wdrażania.
Wygeneruj parę kluczy
# Generate private keyopenssl genrsa -out private_key.pem 4096 openssl rsa - private_key.pem -pubout -out public_key.pemUdostępnij plik public_key.pem w Zonos. Przechowuj plik private_key.pem w dedykowanym menedżerze tajemnic (AWS Secrets Manager, HashiCorp Vault, itp.) — nigdy w kontroli źródła lub zmiennych środowiskowych.
Zonos zarejestruje Twój klucz i zwróci Twój identyfikator organizacji, który staje się roszczeniem iss we wszystkich asercjach JWT.
Krok 2 — Zbuduj asercję JWT
Podpisz JWT za pomocą RS256 przy użyciu swojego klucza prywatnego. Asercja jest ważna dla pojedynczej wymiany tokenów — utrzymuj okno ważności krótkie (60–300 sekund).
Wymagane roszczenia
| Roszczenie↕ | Wartość↕ |
|---|---|
iss | Twój identyfikator organizacji Zonos (np. "org_abc123") |
sub | Identyfikuje usługę wywołującą (np. "checkout-service") |
aud | Musi być dokładnie "zonos-auth" |
exp | Znacznik czasu Unix; 60–300 sekund od iat |
iat | Znacznik czasu Unix wydania |
jti | Unikatowy UUID na asercję (umożliwia wykrywanie powtórzeń) |
Nagłówek JWT musi określić "alg": "RS256" i "typ": "JWT".
Przykłady kodu
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",)Krok 3 — Wymień asercję na token dostępu
Wyślij podpisany JWT do punktu końcowego tokenu Zonos, aby otrzymać krótkotrwały token nośnika.
Punkt końcowy
POST https://auth.zonos.com/oauth/token
Content-Type: application/json
Obsługiwany jest również application/x-www-form-urlencoded.
Pola żądania
| Pole↕ | Wymagane↕ | Wartość↕ |
|---|---|---|
grant_type | Tak | "urn:ietf:params:oauth:grant-type:jwt-bearer" |
assertion | Tak | Twój podpisany JWT (zwartej serializacji) |
Żądanie i odpowiedź
{ "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}| Pole odpowiedzi↕ | Opis↕ |
|---|---|
access_token | Token nośnika dla wszystkich kolejnych żądań API |
token_type | Zawsze "Bearer" |
expires_in | Sekund do wygaśnięcia (domyślnie: 300) |
scope | Uprawnienia rozdzielone spacjami przyznane temu tokenowi |
Pełne przykłady kodu
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"]Krok 4 — Wywołaj interfejsy API Zonos za pomocą tokenu dostępu
Dołącz token dostępu jako token Bearer w nagłówku Authorization w każdym żądaniu API Zonos.
Przykładowe żądanie
curl -X POST https://api.zonos.com/graphql \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "query": "{ ... }" }'Cykl życia tokenu i buforowanie
Tokeny dostępu wygasają w ciągu 5 minut domyślnie. Buforuj token i odśwież proaktywnie — nie żądaj nowego tokenu przy każdym wywołaniu API. Każde odświeżenie wymaga nowo podpisanej asercji JWT.
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"]Odniesienie błędów
Wszystkie błędy podlegają formatowi odpowiedzi błędu OAuth 2.0 (RFC 6749 §5.2):
{ "error": "invalid_grant", "error_description": "JWT assertion has expired"}| Kod stanu HTTP↕ | error↕ | Przyczyna↕ |
|---|---|---|
400 | unsupported_grant_type | grant_type nie była urn:ietf:params:oauth:grant-type:jwt-bearer |
400 | invalid_request | Brakujące lub nieprawidłowo sformatowane pole |
401 | invalid_grant | Nieprawidłowy podpis, wygasła asercja, nieznana organizacja, lub niezarejestrowany klucz |
500 | server_error | Błąd wewnętrzny — skontaktuj się z obsługą Zonos, jeśli problem się utrzymuje |
Typowe przyczyny invalid_grant:
expjest w przeszłości — upewnij się, że zegar systemu jest synchronizowany NTPaudnie jest dokładnie"zonos-auth"issnie odpowiada zarejestrowanemu identyfikatorowi organizacji- Klucz publiczny został obrócony, ale nie został jeszcze zaktualizowany w Zonos
Najlepsze praktyki bezpieczeństwa
- Chroń swój klucz prywatny. Przechowuj go w dedykowanym menedżerze tajemnic — nigdy w kontroli źródła, zmiennych środowiskowych ani logach.
- Utrzymuj asercje krótkotrwałe. 60–300 sekund jest standardowe; nie ma powodu, aby wydawać dłuższe.
- Dołącz
jti. Unikatowa wartość na asercję umożliwia wykrywanie powtórzeń po stronie serwera. - Obracaj pary kluczy okresowo. Zarejestruj nowy klucz publiczny w Zonos przed cofnięciem starego, aby uniknąć przestojów.
- Nigdy nie rejestruj wartości
access_tokenlubassertion. Traktuj oba jako poświadczenia.
Uwierzytelnianie OAuth 2.0
Uwierzytelniaj usługi zaplecza w Zonos przy użyciu asymetrycznej kryptografii klucza — bez wspólnych tajemnic.
Zonos obsługuje uwierzytelnianie maszyna-do-maszyny za pośrednictwem OAuth 2.0 JWT Bearer Token Grant (RFC 7523). Twoja usługa podpisuje krótkotrwały JWT swoim prywatnym kluczem RSA; Zonos weryfikuje go za pomocą zarejestrowanego klucza publicznego i zwraca token nośnika ograniczony do twojej organizacji.
Podsumowanie przepływu:
Authorization: Bearer <token>w każdym żądaniu API.