DOCS

Аутентификация OAuth 2.0

Аутентификация OAuth 2.0

Аутентифицируйте свои серверные сервисы с помощью Zonos, используя асимметричную криптографию с открытым ключом — без общих секретов.

Zonos поддерживает аутентификацию между машинами через OAuth 2.0 JWT Bearer Token Grant (RFC 7523). Ваш сервис подписывает краткосрочный JWT своим приватным ключом RSA; Zonos проверяет его, используя ваш зарегистрированный открытый ключ, и возвращает токен Bearer в области вашей организации.

Краткое описание потока:

  1. Создайте пару ключей RSA и зарегистрируйте свой открытый ключ с Zonos.
  2. Во время выполнения подпишите JWT-утверждение с помощью своего приватного ключа и отправьте его на конечную точку токена.
  3. Zonos возвращает токен доступа с ограниченным временем действия.
  4. Включите токен доступа как Authorization: Bearer <token> на каждый запрос API.

Создайте пару ключей RSA размером 4096 бит и поделитесь открытым ключом с Zonos. Это делается один раз при онбординге.

Создание пары ключей

1# Генерируем приватный ключ
2openssl genrsa -out private_key.pem 4096
3 
4# Извлекаем открытый ключ
5openssl rsa -in private_key.pem -pubout -out public_key.pem

Поделитесь public_key.pem с Zonos. Сохраните private_key.pem в специальный менеджер секретов (AWS Secrets Manager, HashiCorp Vault и т. д.) — никогда не сохраняйте в системе контроля версий или переменных окружения.

Zonos зарегистрирует ваш ключ и вернет ваш идентификатор организации, который становится утверждением iss во всех JWT-утверждениях.

Подпишите JWT с помощью RS256, используя свой приватный ключ. Утверждение действительно для одного обмена токенами — сохраняйте окно истечения коротким (60–300 секунд).

Требуемые утверждения

УтверждениеЗначение
issВаш идентификатор организации Zonos (например "org_abc123")
subОпределяет вызывающий сервис (например "checkout-service")
audДолжно быть точно "zonos-auth"
expВременная метка Unix; 60–300 секунд от iat
iatВременная метка Unix издания
jtiУникальный UUID для каждого утверждения (включает обнаружение воспроизведения)

Заголовок JWT должен указывать "alg": "RS256" и "typ": "JWT".

Примеры кода

1import jwt, uuid, time
2 
3with open("private_key.pem") as f:
4 private_key = f.read()
5 
6now = int(time.time())
7assertion = jwt.encode(
8 {
9 "iss": "org_abc123",
10 "sub": "checkout-service",
11 "aud": "zonos-auth",
12 "iat": now,
13 "exp": now + 300,
14 "jti": str(uuid.uuid4()),
15 },
16 private_key,
17 algorithm="RS256",
18)

Отправьте подписанный JWT на конечную точку токена Zonos, чтобы получить краткосрочный токен Bearer.

Конечная точка

POST https://auth.zonos.com/oauth/token
Content-Type: application/json

Также принимается application/x-www-form-urlencoded.

Поля запроса

ПолеТребуетсяЗначение
grant_typeДа"urn:ietf:params:oauth:grant-type:jwt-bearer"
assertionДаВаш подписанный JWT (компактная сериализация)

Запрос и ответ

1{
2 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
3 "assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
4}
Поле ответаОписание
access_tokenТокен Bearer для всех последующих запросов API
token_typeВсегда "Bearer"
expires_inСекунды до истечения (по умолчанию: 300)
scopeРазделенные пробелом разрешения, предоставленные этому токену

Полные примеры кода

Включите токен доступа как токен Bearer в заголовке Authorization для каждого запроса к API Zonos.

Пример запроса

1curl -X POST https://api.zonos.com/graphql \
2 -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
3 -H "Content-Type: application/json" \
4 -d '{ "query": "{ ... }" }'

Жизненный цикл токена и кеширование 

Маркеры доступа по умолчанию истекают через 5 минут. Кешируйте токен и обновляйте его упреждающе — не запрашивайте новый токен при каждом вызове API. Каждое обновление требует вновь подписанного JWT-утверждения.

1import time, requests
2 
3_cache = {"access_token": None, "expires_at": 0}
4 
5def get_access_token():
6 if time.time() < _cache["expires_at"] - 30:
7 return _cache["access_token"]
8 
9 assertion = build_jwt_assertion()
10 data = requests.post(
11 "https://auth.zonos.com/oauth/token",
12 json={
13 "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
14 "assertion": assertion,
15 },
16 ).json()
17 
18 _cache["access_token"] = data["access_token"]
19 _cache["expires_at"] = time.time() + data["expires_in"]
20 return _cache["access_token"]

Справочник ошибок 

Все ошибки следуют формату ответа об ошибке OAuth 2.0 (RFC 6749 §5.2):

1{
2 "error": "invalid_grant",
3 "error_description": "JWT assertion has expired"
4}
HTTP СтатусerrorПричина
400unsupported_grant_typegrant_type был не urn:ietf:params:oauth:grant-type:jwt-bearer
400invalid_requestОтсутствует или неправильный формат поля
401invalid_grantНеверная подпись, истекшее утверждение, неизвестная организация или незарегистрированный ключ
500server_errorВнутренняя ошибка — обратитесь в поддержку Zonos, если она сохраняется

Распространенные причины invalid_grant:

  • exp находится в прошлом — убедитесь, что ваши системные часы синхронизированы с NTP
  • aud не является точно "zonos-auth"
  • iss не совпадает с вашим зарегистрированным идентификатором организации
  • Открытый ключ был ротирован, но еще не обновлен с Zonos

Лучшие практики безопасности 

  • Защитите свой приватный ключ. Сохраняйте его в специальном менеджере секретов — никогда не сохраняйте в системе контроля версий, переменных окружения или журналах.
  • Сохраняйте утверждения краткосрочными. 60–300 секунд — это стандартно; нет причин выпускать более длительные.
  • Включите jti. Уникальное значение для каждого утверждения позволяет серверу обнаруживать воспроизведения.
  • Периодически ротируйте пары ключей. Зарегистрируйте новый открытый ключ с Zonos перед отзывом старого, чтобы избежать простоев.
  • Никогда не логируйте значения access_token или assertion. Обращайтесь с обоими как с учетными данными.

Была ли эта страница полезной?


На этой странице: