47 lines
3.4 KiB
Markdown
47 lines
3.4 KiB
Markdown
# ADR-002: привязка пользователей Битрикс24 и Telegram
|
||
|
||
**Статус:** Принято
|
||
**Дата:** 2026-07-23
|
||
|
||
## Контекст
|
||
|
||
Локальное приложение CRM отправляет на HTTPS-адрес `/bitrix/bind`
|
||
идентификационные данные пользователя и refresh-токен. Идентификаторам портала и
|
||
пользователя из входной формы доверять нельзя: контекст должен быть получен от
|
||
OAuth-сервера Битрикс24 и подтверждён методом `user.current`.
|
||
|
||
## Решение
|
||
|
||
Сайт использует refresh-токен для получения новой OAuth-пары, доверенных
|
||
`member_id`, `user_id` и `client_endpoint`. После этого `BitrixClient` сверяет
|
||
`user_id` с результатом `user.current`.
|
||
|
||
Процесс привязки учётных записей представлен на диаграмме последовательности.
|
||
|
||

|
||
|
||
*Рисунок ADR-002/1. Диаграмма последовательности привязки Битрикс24 к Telegram*
|
||
|
||
После проверки пользователя функцией `secrets.token_urlsafe(32)` формируется
|
||
одноразовый токен привязки. В БД записывается только SHA-256-хеш, поэтому
|
||
компрометация базы не позволяет восстановить действующую ссылку. Срок жизни
|
||
задаётся переменной окружения `BINDING_TOKEN_TTL_SECONDS`, ограничен диапазоном
|
||
от 60 до 3600 секунд и по умолчанию равен 600 секундам. При повторном выпуске
|
||
прежние непогашенные токены того же пользователя отзываются.
|
||
|
||
Пользователь переходит по одноразовой ссылке в чат с Telegram-ботом. Бот
|
||
повторно вычисляет SHA-256-хеш и сверяет его с активными токенами. Если токен
|
||
существует, не истёк, не отозван и ещё не погашен, он помечается использованным,
|
||
а в таблице привязок создаётся или обновляется связь пользователя Битрикс24 с
|
||
аккаунтом Telegram.
|
||
|
||
Погашение выполняется только в личном чате. Проверка токена и изменение привязки
|
||
выполняются функцией `binding.consume_v1` в одной транзакции.
|
||
|
||
## Последствия
|
||
|
||
Привязка не использует идентификаторы пользователя из недоверенной входной
|
||
формы. В базе хранится только хеш одноразового токена, а повторный выпуск ссылки
|
||
отзывает предыдущие непогашенные токены. Атомарное погашение не позволяет двум
|
||
запросам одновременно использовать одну ссылку.
|