# Идентификация через токен

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

!!! Note "N.B."
    Данная статья содержит техническое описание сервиса токенизации, необходимого для безопасной авторизации и идентификации клиентов при взаимодействии с чат-сервисом Webim, без передачи персональных данных через открытую сеть.

![Cхема авторизации через токенизатор](https://webim.ru/kb/img/dev/identification/scheme-token.svg)

## Функциональные требования к сервису токенизации

### Генерация временных токенов:

  * Сервис должен генерировать уникальные временные токены для каждого клиента.

  * Токен должен представлять собой уникальную последовательность символов (буквы, цифры).

  * Токен не должен содержать в себе персональные данные клиента.

  * Рекомендуемый формат: UUID v4 или аналогичный криптографически стойкий идентификатор.

### Хранение соответствия токенов и данных клиента:

  * Сервис должен хранить соответствие между токеном и внутренним ID клиента.

  * Необходимо предусмотреть механизм очистки устаревших токенов.

  * Рекомендуемое время жизни токена: от 30 минут до 24 часов.

### API для внутреннего взаимодействия:

  * Метод получения токена по ID клиента.

  * Метод валидации токена и получения связанных данных клиента.

## Процесс работы с токенизацией

### Авторизация пользователя

  1. **Пользователь** заходит на страницу авторизации сайта или мобильного приложения, далее **МП**.

  1. Если **Пользователь** не авторизирован, то вводит свои идентификационные данные (логин, пароль, и т.д.).

  1. **МП** проверяет валидность учетных данных.

  1. После успешной авторизации **Пользователь** получает доступ в авторизованную зону.
  
### Генерация токена:

  1. При переходе **Пользователя** на страницу с чатом сервер **МП** запрашивает токен у сервиса токенизации.

  1. Сервис токенизации генерирует уникальный временный токен.

  1. Токен связывается с внутренним ID клиента и его персональными данными (ФИО, телефон и т.д.).

  1. Сервис токенизации возвращает сгенерированный токен серверу **МП**.

### Передача данных в Webim через API:

  1. Сервер **МП** вызывает метод API системы **Webim** [`provide_visitor_fields`](https://webim.ru/kb/dev/api/realtime-2.0.html#provide-visitor-fields).

  1. В запросе передаются временный токен (`auth_token`), ID Пользователя (id) и персональные данные Пользователя (ФИО, телефон и т.д.).

  1. Система **Webim** сохраняет эти данные, связывая их с переданным токеном.

  1. Важно: данный запрос выполняется внутри защищенной сети **МП**, персональные данные не передаются через интернет.

### Инициализация чата

  1. Токен передается на фронтенд в авторизованной зоне через JavaScript переменную: `window.webim_auth_token = <auth_token>`.

  1. Если для аккаунта включена [маршрутизация посетителей](https://webim.ru/kb/for-admins/visitor-routing.html), на той же странице задайте объект `window.chat_routing_fields` с полями, по которым настроены правила. Поля из `provide_visitor_fields` виджету недоступны и в выборе размещения не участвуют.

  1. Виджет чата на стороне **Пользователя** инициализирует сессию, передавая только токен (без персональных данных).

  1. Система **Webim** получает запрос на создание чата с токеном.

  1. Система **Webim** находит в своей базе данные **Пользователя** по переданному токену.

  1. Создается сессия чата с предзаполненными данными **Пользователя**.

  1. В интерфейсе оператора отображаются персональные данные клиента (ФИО, телефон).

### Технические требования к реализации

  1. Протоколы взаимодействия:

    Все API-запросы должны использовать HTTPS. Также рекомендуется использовать взаимную аутентификацию (mutual TLS) между серверами.

  1. Производительность:

    Генерация токена должна происходить в течение не более 100 мс. При этом система должна поддерживать не менее 1000 запросов в секунду.

  1. Отказоустойчивость:

    Необходимо предусмотреть механизмы репликации данных. Также рекомендуется настроить мониторинг состояния сервиса.
 
### Интеграция с Webim

Для интеграции с сервисом **Webim** необходимо использовать API:

#### Метод [`provide_visitor_fields`](https://webim.ru/kb/dev/api/realtime-2.0.html#provide-visitor-fields)

  * **Итоговый URL**: https://{hostname}/api/v2/rt/provide_visitor_fields

  * **Тип запроса**: POST

  * **Content-Type**: application/json

  * **Формат тела запроса**: JSON

Запрос позволяет провести полнофункциональную авторизацию **Пользователя**,зарегистрированного в **Webim**, из внешней (относительно **Webim Server**) системы c использованием токенизатора.

#### Важные замечания:

  1. Программно-аппаратная часть (бэкенд) внешней системы должна уметь генерировать комбинации токенов и предоставленных полей **Пользователя**.

  1. Пользовательский интерфейс (фронтенд) внешней системы должен содержать следующий JavaScript-код: `window.webim_auth_token = <auth_token>;`.

  1. На страницах не должно быть объекта `webim_visitor`, который содержит идентифицирующие данные.

  1. При успешном использовании метода у **Пользователя** не будет возможности ввести контактную информацию в виджете чата.

  1. Фронтенд внешней системы должен иметь имплементированный обработчик для события ошибки: `window.webimHandlers.onProvidedTokenNotFoundError`.

     В `webim-server` версии `10.8` и выше при ошибке `provided-auth-token-not-found` (когда токен больше не найден на стороне сервера, например после истечения срока действия) фронтенд виджета вызывает этот обработчик; до обновления токена виджет продолжает попытки подключения. В обработчике на стороне клиентского приложения нужно запросить новый токен у своего бэкенда, обновить `window.webim_auth_token` и вызвать `window.webim.api.onAuthTokenChanged()`, чтобы виджет перезапустился уже с новым токеном. Если обработчик не переопределен, будет вызван пустой обработчик по умолчанию: токен не обновится, и виджет продолжит повторные попытки подключения.

  1. Когда **Пользователь** выходит из системы, бэкенд должен отправить на сервер **Webim** POST-запрос в метод [`provide_visitor_fields`](https://webim.ru/kb/dev/api/realtime-2.0.html#provide-visitor-fields) с токеном и без `visitor_fields`, при этом комбинация токен-поля будет удалена.

    ![Cхема закрытия сесcии](https://webim.ru/kb/img/dev/identification/scheme-token-close.svg)

  1. Если для аккаунта включена [маршрутизация посетителей](https://webim.ru/kb/for-admins/visitor-routing.html), поля, по которым настраиваются правила, нужно передавать на фронтенде через объект `window.chat_routing_fields` (см. [описание](https://webim.ru/kb/dev/identification/id-2-0.html#chat-routing-fields)). Это обязательно и при идентификации по токену: поля из `provide_visitor_fields` хранятся на сервере и не используются виджетом при выборе размещения.

     Пример:

     ```
     window.webim_auth_token = '<auth_token>';
     window.chat_routing_fields = {
         subscription_type: 'premium'
     };
     ```

#### Пример тела запроса:

```
{
    "auth_token": "40bbba7cd1fec39dd1aXXXXXXXXXXX",
    "visitor_fields": {
    "id": "a1e29384df",
    "display_name": "John Bull",
    "email": "john@webim.ru",
    "phone": "+7 123 123 123"
  }
}
```

#### Параметры запроса:

| Имя                                    | Тип                  | Описание                                                                                                                                                                            |
|----------------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| auth_token                             | str                  |Уникальный, псевдослучайный идентификатор (токен). Обязательное поле. Может быть любой строкой (например, UUID).                                                                     |
| visitor_fields                         | Object               |Структура с предоставленными полями посетителя. Необязательное поле. Если присутствует, добавляет/замещает комбинацию "токен-поля". Если отсутствует, комбинация удаляется из памяти.|
| id                                     | str                  |Идентификатор посетителя в системе организации. Обязательное поле, если присутствует объект `visitor_fields.`                                                                        |
| [Другие&nbsp;поля]                     | str                  |Любые персональные данные посетителя, которые нужно передать на сервер.                                                                                                              |

#### Возвращаемые значения:

  * **200** – запрос выполнен успешно: `{ "result": "ok" }`.

  * **401** – авторизационные данные не прошли проверку: `{ "error": "unauthorized" }`.

  * **502** – сервер не готов обработать запрос (Bad Gateway).


Ошибки с кодом **200**: `{ "error": "<error-name>" }`. Возможные ошибки:

  * `auth-token-is-not-string`: Неверный тип данных в поле токена.

  * `request-body-is-not-object`: Неверный формат исходных данных.

  * `request-body-is-not-valid-json`: Недействительный JSON-объект.

  * `mandatory-field-not-found`: Не указан токен.

  * `id-field-required`: В [`visitor_fields`](https://webim.ru/kb/dev/api/realtime-2.0.html#provide-visitor-fields) отсутствует параметр id.

  * `field-name-is-not-string`: В [`visitor_fields`](https://webim.ru/kb/dev/api/realtime-2.0.html#provide-visitor-fields) имеется ключ/значение, указанное не строкой.

---

Источник: https://webim.ru/kb/dev/identification/authorization-scheme-tokenizer.html
