В интеграциях с внешними приложениями часто используется протокол OAuth 2.0. В этой статье разбирается практический сценарий: получение access_token, обновление токена, работа с ошибками и использование токена аккаунта для фоновых операций. Статья будет полезна системным аналитикам и backend-разработчикам, которые проектируют интеграции с внешними API, используют OAuth 2.0 и хотят разобраться в практических сценариях — включая фоновые операции. Читать далее
В интеграциях с внешними приложениями часто используется протокол OAuth 2.0. Он позволяет приложению получить доступ к данным пользователя без передачи пароля. В этой статье разбирается практический сценарий: получение access_token, обновление токена, работа с ошибками и использование токена аккаунта для фоновых операций.
Подробная диаграмма последовательности процесса авторизации.

Диаграмма процесса авторизации по OAuth 2.0
Далее описан алгоритм авторизации по протоколу OAuth 2.0.
Пользователь переходит из страницы настройки интеграции в стороннее приложение. В URL передаются параметры аккаунта: account_id и account_name
https://%domain%.ru/api/oauth2/auth?account\_id=<идентификатор аккаунта>&account_name=<наименование аккаунта>Стороннее приложение сохраняет account_id (идентификатор аккаунта) и account_name(наименование аккаунта). Они потребуются при создании подключения и получении токена аккаунта.
Приложение перенаправляет пользователя на сервер аутентификации для получения кода авторизации — authorization code :
https://id.provider.com/authorizeПараметры запроса:
Параметр | Описание |
| Идентификатор стороннего приложения |
| URL, на который сервер авторизации перенаправляет пользователя после успешной авторизации. |
| Запрашиваемые права стороннего приложения |
| Защита от подделки |
https://id.provider.com/authorize?
client_id=1xx1x111-1x11-1111-1xx1-x1xx1xx1xx1x
&redirect_uri=http://example.com/callback
&scope=<права стороннего приложения>
&state=123После успешного входа сервер возвращает временный код авторизации, который может быть использован только один раз — authorization code. Время жизни кода ограничено.
Сервер стороннего приложения выполняет POST-запрос к серверу аутентификации:
curl -X POST https://id.provider.com/token \
-H "Authorization: Basic base64(client_id:client_secret)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "code=AUTHORIZATION_CODE" \
-d "grant_type=authorization_code" \
-d "redirect_uri=https://your-app.com/callback"Параметры запроса:
Параметр | Описание |
| Временный код, полученный на предыдущем шаге |
|
|
| URL возврата (должен совпадать с указанным ранее) |
В ответе приходит json с access_token и refresh_token. Формат успешного ответа, если access_token получен:
{
"token_type": "Bearer",
"user_id": "1111111ч-11x-1111-xx11-x1x111x11111",
"expires_in": 3600,
"expires_at": "2026-01-01T10:10:10+03:00",
"access_token": "<accesstoken>",
"refresh_token": "<refreshtoken>",
"refresh_expires_in": 2500000,
"refresh_expires_at": "2028-01-01T12:04:54+03:00"
}Параметры ответа:
Параметр | Описание |
| Всегда |
| Уникальный идентификатор пользователя |
| Время жизни |
| Дата и время истечения |
| Токен доступа (короткоживущий, обычно 1 час) |
| Токен для обновления |
| Время жизни |
| Дата и время истечения |
Формат ответа при ошибке
{
"error": "invalid_grant",
"error_description": "Code is expired."
}После получения access_token приложение создаёт подключение в ресурсном сервере:
curl -X POST https://account.provider.com/api/rest/create.json \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{}' В случае успешного запроса, в ответе вернется app_id — идентификатор подключения.
Срок жизни access_token ограничен. После истечения срока жизни токена пользователю необходимо вновь пройти авторизацию. Чтобы не проходить авторизацию заново, когда access_token истекает, его обновляют через refresh_token. refresh_token всегда выдается с access_token в одном ответе.
curl -X POST https://id.provider.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=<указать полученный ранее refresh_token>" \
-d "client_id=<Идентификатор стороннего приложения >" В результате токен обновится или появится информация об ошибке.
После получения access_token приложение создаёт подключение в ресурсном сервере с помощью запроса:
curl -X POST https://account.provider.com/api/rest/create.json \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}' В случае успешного запроса, в ответе вернется app_id — идентификатор подключения.
После получения пользовательского access_token и refresh_token возникает вопрос: что делать, если интеграции нужно работать в фоне — без участия пользователя? В таких случаях используется токен аккаунта (account_token).
Без токена аккаунта фоновые операции привязаны к конкретному пользователю. Если пользователь выйдет из системы или его сессия истечёт — интеграция перестанет работать. Токен аккаунта привязан не к пользователю, а к аккаунту, и может работать независимо.
Пример запроса на получение access_token аккаунта
curl -X POST https://id.provider.com/token \
-H "Authorization: Basic base64(client_id:client_secret)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=account_token" \
-d "access_token=USER_ACCESS_TOKEN" \
-d "account_client_id=111x1111-x111-x111-xx1x-111x11x111xx" \
-d "account_id=111"Для фоновых операций используй токен аккаунта — он не привязан к сессии пользователя и подходит для автоматических сценариев.
access_token имеет ограниченный срок жизни — следует обновлять его заранее через refresh_token, чтобы избежать сбоев в работе интеграции
Не выводить токены в логи
Заложить права доступа не только на сервере, но и в приложении, чтобы корректно обрабатывать ошибки
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Оптимизация без AI: как я автоматизировал API-ручки и типы | -2 | 5 | 29-06-2026 |
| 2 | Микрофронтенды. Стабильная интеграция нескольких SPA-приложений. Часть 1 | 0 | 5 | 29-06-2026 |
| 3 | Микрофронтенды. Стабильная интеграция нескольких SPA-приложений. Часть 2 | 0 | 5 | 30-06-2026 |
| 4 | DTO, schema, model, entity: почему в коде всё называется User | 0 | 7 | 01-07-2026 |
| 5 | Настройка AI-агентов для ускорения бизнес процессов компании | 0 | 7 | 03-07-2026 |
| 6 | Полный гайд по JavaScript-коду отслеживания в Matomo. Часть 1 | 0 | 7 | 08-07-2026 |
| 7 | Как я навайбкодил каталог бесплатных парковок Петербурга и России | 5 | 7 | 07-07-2026 |
| 8 | Baseline: май 2026 | 0 | 5 | 29-06-2026 |
| 9 | База по системному дизайну для начинающих разработчиков ПО на примере. Часть 1. Анализ задачи, декомпозиция, модули | 5 | 7 | 04-07-2026 |
| 10 | Актуальность техстека как задача: наш путь от хаоса к регулярным SLA-апдейтам | 5 | 7 | 26-06-2026 |