Skip to content
This page is currently available in Russian only.
Инвойсбокс

Стандартный OAuth 2.1

Инвойсбокс ID подключается по стандарту. Параметры и ответы называются так, как их ждут готовые библиотеки OAuth, поэтому обмен не приходится писать руками. Библиотеке достаточно указать issuerhttps://api.invoicebox.ru, остальные адреса она прочитает из метаданных.

Что нужно получить заранее

Идентификатор приложения (client_id), список адресов возврата и набор прав запрашиваются у службы поддержки. Права — это именованные наборы, те же, что видны в личном кабинете: приложение не может попросить больше, чем ему разрешили при регистрации, а пользователь на экране согласия видит их человеческими названиями, а не кодами.

Какие права бывают

Перечень полный — scope принимает только эти коды, через пробел.

КодЧто разрешает
merchant-readпросмотр заказов и платежей
merchant-orderсоздание заказов
merchant-refundвозвраты
merchant-notification-readпросмотр журнала уведомлений
merchant-notification-resendпереотправка уведомлений из журнала
merchant-document-readпросмотр отчётных документов

Просить больше, чем нужно, не надо. Пользователь видит запрошенное на экране согласия, и лишняя строка — это причина отказать. Незнакомый код или право, которого у приложения нет, отклоняются с invalid_scope.

Параметр scope можно не передавать — тогда запрашиваются все права, разрешённые приложению при регистрации. Это не «минимум», а «максимум»: удобно начинать, но для боевого запуска перечисляйте нужное явно. Список прав приложения со временем расширяется, и «все» завтра означает больше, чем сегодня.

Со своей стороны мы просим у службы поддержки узкий список прав для новых приложений — ровно под задачу, а не «как у менеджера магазина». Если вам выдали больше, чем нужно, скажите: сузить список проще, чем потом объяснять пользователю, почему на экране согласия просят доступ к возвратам.

Что пользователь действительно разрешил, говорит не ваш запрос, а ответ: поле scope при обмене кода и поле scopes в профиле. Проверять права нужно по ним.

Секрет приложения выдаётся только тем, кто хранит его на сервере. Приложению, которое работает в браузере или на устройстве, секрет не нужен и не выдаётся: его невозможно там спрятать.

Метаданные сервера авторизации

Адреса не нужно хранить в коде — сервер сообщает их сам (RFC 8414).

  • метод: GET
  • ресурс: /.well-known/oauth-authorization-server
{
  "issuer": "https://api.invoicebox.ru",
  "authorization_endpoint": "https://id.invoicebox.ru/oauth/authorize",
  "token_endpoint": "https://api.invoicebox.ru/v3/security/oauth/token",
  "revocation_endpoint": "https://api.invoicebox.ru/v3/security/oauth/revoke",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_post", "none"]
}

Библиотеки OAuth читают этот документ сами, и обычно достаточно указать им issuer. Ответ 404 означает, что стандартные адреса в этой установке ещё не включены.

Обратите внимание, где что лежит. Сам документ — в корне хоста: его адрес выводится из issuer по правилам стандарта, и клиент собирает его сам. А адреса обмена и отзыва берутся из документа и лежат вместе с остальным API, под /v3/security/oauth/. Не собирайте их руками из issuer — читайте из метаданных, тогда переезд адресов вас не коснётся.

Рядом лежит второй документ — /.well-known/oauth-protected-resource: он описывает уже сам API как ресурс и называет сервер авторизации, у которого для него просят токен. Именно на него указывает подсказка в отказе 401.

Как проходит вход

Четыре запроса, каждый на своей странице — по порядку, в котором они и делаются:

  1. Экран согласия — пользователь видит, какое приложение просит доступ и какие права, и разрешает или отклоняет.
  2. Обмен кода на токен — ваш сервер меняет одноразовый код на пару токенов.
  3. Обновление токена — когда срок access-токена истёк.
  4. Отзыв доступа — когда доступ больше не нужен.

Ниже — то, что относится к потоку целиком: ограничение токена одним сервисом, обязательность PKCE и коды ошибок.

Ограничение токена одним сервисом

Параметр resource (RFC 8707) говорит, для какого нашего сервиса нужен токен. Указали — токен принимается только там; в другом сервисе он не сработает, даже если прав хватает.

Это защита от посредника. Приложение, которому доверили доступ к одному сервису, не должно уметь тем же токеном сходить в другой — а без указанного ресурса токен принимается всюду, где хватает прав.

Значение — адрес сервиса, целиком и без якоря, например https://mcp.invoicebox.ru/mcp. Незнакомый адрес отклоняется с invalid_target: список известных ресурсов задаём мы, иначе токен получил бы аудиторию, которую никто не проверяет. Указанный на первом шаге ресурс должен повториться при обмене кода — иначе приложение получило бы доступ не туда, куда согласился пользователь.

PKCE обязателен

code_challenge и code_verifier нужны всем приложениям, включая серверные с секретом. Причина не в формальности: код возвращается через браузер пользователя, а секрет приложения в этом обмене не участвует — перехваченный код без code_verifier бесполезен, с секретом или без.

Поддерживается только метод S256. Приложения, зарегистрированные до этого требования, продолжают работать по-прежнему, но при обновлении клиента стоит добавить PKCE: включение по одному приложению делается по вашему запросу.

Ошибки

Отказы приходят по стандарту: код в поле error, пояснение для разработчика — в error_description.

{
  "error": "invalid_grant",
  "error_description": "code: authorization code has expired"
}
КодЧто случилосьЧто делать
invalid_requestне хватает параметра или он пустойисправить запрос
invalid_clientclient_id неизвестен или приложение отключенопроверить идентификатор; отвечает 401
invalid_grantкод или токен обновления не подошёл: истёк, уже использован, выпущен для другого адреса возвратапройти авторизацию заново
unsupported_grant_typeтакой способ получения токена не поддерживаетсяиспользовать authorization_code или refresh_token
invalid_scopeзапрошены права, которых у приложения нетсогласовать права с поддержкой
invalid_targetнезнакомый или несовпадающий resourceпроверить адрес сервиса

Читайте также

In this section

Was this page helpful?