Почти все команды ModusBI API требуют активной сессии пользователя. Исключения составляют команды входа, команды EULA и несколько публичных эндпоинтов (см. раздел «Команды без токена»).

Для выполнения защищенных запросов внешнее приложение должно пройти процесс аутентификации и получить токен сессии. Токен передается в каждом последующем вызове API.

Команда login/create

Команда login/create выполняет аутентификацию пользователя и возвращает параметры учетной записи. В случае необходимости принятия пользовательского соглашения EULA процесс аутентификации прерывается до принятия соглашения.

Запрос:

  • URL: <protocol>://<host>/<path_to_api>/login
  • Пример URL: https://dev.modusbi.ru/v1/api/login
  • Тип запроса: POST;
  • Тип данных тела запроса: JSON.

Тело запроса:

{
  "object": {"name": "login"},
  "command": {"name": "create"},
  "data": [{
    "username": "admin",
    "password": "********",
    "pcid": 1
  }]
}

Параметры:

Поле Назначение
username Логин пользователя портала
password Пароль
pcid Идентификатор конфигурации провайдера аутентификации. Для встроенного входа ModusBI обычно 1. Если передать 0 или опустить — сервер подставит провайдер по умолчанию для пользователя или портала

Пример curl:

curl -s -X POST 'https://<host>/v1/api/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "object": {"name": "login"},
    "command": {"name": "create"},
    "data": [{"username": "admin", "password": "********", "pcid": 1}]
  }'

Справочник: login/create.

Что делает сервер (пошагово)

Клиент отправляет один HTTP-запрос login/create. Внутри сервер выполняет цепочку шагов — отдельно вызывать их не нужно. Ниже в таблице перечислен порядок обработки входа и соответствующий ответ клиенту:

Этап Что происходит Результат для клиента
1 Проверка параметров Валидация username, password, pcid При ошибке — status ≠ 200, сообщение в message
2 Выбор провайдера По pcid загружается конфигурация аутентификации (локальный ModusBI, LDAP, OAuth и т.д.)
3 Аутентификация Проверка логина и пароля (или сценарий внешнего провайдера) «Неверный Пользователь или Пароль», блокировка учетной записи (УЗ) и др.
4 Состояние УЗ Проверка, что учетная запись активна, не истекла Сообщение в message или loginMessage
5 Профиль и роль Назначение роли, профилей доступа, переменных пользователя Служебные шаги, в ответе не видны
6 Проверка EULA Сравнение принятой пользователем версии соглашения с актуальной Если не принято — ветка EULA (токен не выдается)
7 Создание сессии Открытие сеанса, генерация JWT
8 Формирование ответа Запись события входа, сбор данных профиля data.token, roleID, permissions, ФИО и др.

 

Варианты ответа login/create

Сервер возвращает HTTP-код 200 при успешной обработке запроса, однако наличие этого кода не гарантирует выдачу токена. Возможны следующие сценарии:

1. Аутентификация пройдена, принятие EULA не требуется.

Сохраните data.token. Остальные поля (roleID, permissions, username и т.д.) описывают учетную запись.

{
  "mode": "online",
  "status": 200,
  "message": "",
  "data": {
    "ID": 1,
    "username": "admin",
    "roleID": 1,
    "roleName": "Администратор",
    "token": "eyJ0eXAiOiJKV1QiLCJhbGci...",
    "permissions": [{"edit": 1, "settings": 1, "view": 1}],
    "loginMessage": ""
  }
}

Обратите внимание на поле loginMessage. Если оно содержит текст, покажите это сообщение пользователю, так как оно информирует о статусе учетной записи (например, о скором истечении срока действия).

2. Аутентификация пройдена, требуется принятие EULA.

Сервер возвращает HTTP-код 200, но поле data.token отсутствует. Вместо него приходят флаг ожидания и идентификатор отложенных данных:

{
  "mode": "online",
  "status": 200,
  "message": "",
  "data": {
    "eulaAcceptancePending": true,
    "pendingID": "e414c5c7-9b2f-48e0-ae89-39b039434444"
  }
}

В этом сценарии токен не выдается. Для продолжения процесса выполните шаги, описанные в разделе «Пользовательское соглашение (EULA)». Повторно вызывать login/create с тем же логином не нужно, пока действует pendingID (15 минут).

3. Ошибка входа.

Любой HTTP-код, отличный от 200 (status ≠ 200), либо наличие текста в поле message свидетельствуют об ошибке.

Типичные случаи:

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

4. Внешний провайдер (HTTP 301).

Для pcid внешней системы (Keycloak, OAuth, ЕСИА и т.п.) сервер может вернуть редирект на страницу IdP вместо JSON с токеном. Клиент обрабатывает переход по правилам провайдера. После успешной аутентификации на стороне внешней системы сценарий завершается ответом с data.token или веткой EULA.

Пользовательское соглашение (EULA)

ModusBI может требовать принятия пользовательского соглашения (EULA) перед выдачей токена. Проверка выполняется после успешной проверки логина и пароля, но до создания сессии и поля data.token.

Тип соглашения зависит от лицензии сервера:

Тип лицензии Тип соглашения в БД
Стандартный commercial
Любой иной (ограниченный, пробный и т.д.) trial

 

Текст хранится в метаданных (таблица eula, с поддержкой языков). Подробности для администраторов: Пользовательское соглашение (EULA).

EULA не запрашивается, если:

  • включен режим White Label (ServerWhiteLabel);
  • для типа лицензии нет записей EULA в метаданных;
  • пользователь уже принял актуальную версию соглашения для своего типа лицензии;
  • версия фронтенда ниже 3.15.0 (проверка EULA отключена).

В этих случаях login/create сразу возвращает data.token.

Полный сценарий для клиента API

Шаг EULA-1. Ответ login/create с pendingID

После успешной проверки пароля сервер не выдает токен, а сохраняет отложенные данные входа в памяти сервера и возвращает UUID — pendingID.

В отложенной записи хранятся: идентификатор пользователя, pcid, параметры сессии, eula_id текста, который нужно показать.

Важно:

  1. pendingID действует 15 минут с момента выдачи. После истечения или перезапуска сервера запись теряется — нужен новый login/create.
  2. Команды eula.get_text и eula.resolve выполняются без заголовка Authorization.
  3. Повторный login/create до завершения EULA создаст новый pendingID — используйте тот, что пришел в последнем ответе.

Шаг EULA-2. Получение текста — login/eula.get_text

Команда возвращает текст пользовательского соглашения по идентификатору отложенных данных, выданных в ответе login/create (или login/bind_ids) в варианте ожидания принятия EULA.

Запрос:

  • URL: <protocol>://<host>/<path_to_api>/login
  • Пример URL: https://dev.modusbi.ru/v1/api/login
  • Тип запроса: POST;
  • Тип данных тела запроса: JSON.
{
  "object": {"name": "login"},
  "command": {"name": "eula.get_text"},
  "data": [{
    "pendingID": "e414c5c7-9b2f-48e0-ae89-39b039434444"
  }]
}

Обязательный параметр: pendingID – строка, идентификатор отложенных данных.

При успешном выполнении (код 200) сервер возвращает текст соглашения в поле data.eulaText:

{
  "mode": "online",
  "status": 200,
  "message": "",
  "data": {
    "eulaText": "<p>Текст пользовательского соглашения...</p>"
  }
}

Тело ответа:

  • $.data.eulaText — Строка — Текст EULA;
  • $.message — Строка — Сообщение об ошибке (пусто при успехе);
  • $.status — Число — 200 - успех; иначе - ошибка;
  • $.mode — Строка — Состояние сервиса портала;

Поле data.eulaText может содержать HTML-разметку. Отобразите полученный текст пользователю в интерфейсе приложения.

Иные коды ответа свидетельствуют о ошибке.

Пример curl:

curl -s -X POST 'https://<host>/v1/api/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "object": {"name": "login"},
    "command": {"name": "eula.get_text"},
    "data": [{"pendingID": "e414c5c7-9b2f-48e0-ae89-39b039434444"}]
  }'

Справочник: login/eula.get_text.

Возможные ошибки:

Ситуация Сообщение (публичная часть)
Не передан pendingID Не передан идентификатор отложенных данных
Нет отложенной записи / истек срок (15 мин) Запись отложенных данных не найдена или истекла
Нет текста по eula_id в БД Соглашение не найдено в метаданных

 

Шаг EULA-3. Принятие или отклонение — login/eula.resolve

Команда обрабатывает решение пользователя о принятии или отклонении EULA. Вызывается после того, как пользователь просмотрел текст (полученный отдельной командой eula.get_text по pendingID).

При принятии — сохраняет актуальную версию EULA в профиле пользователя (для типа соглашения по лицензии сервера) и завершает процесс аутентификации пользователя. При отклонении — завершает цепочку входа без авторизации (AccessAllow=false): токен и данные успешного логина не выдаются.

Запрос:

  • URL: <protocol>://<host>/<path_to_api>/login
  • Пример URL: https://dev.modusbi.ru/v1/api/login
  • Тип запроса: POST;
  • Тип данных тела запроса: JSON;

Принятие (пользователь согласился):

{
  "object": {"name": "login"},
  "command": {"name": "eula.resolve"},
  "data": [{
    "pendingID": "e414c5c7-9b2f-48e0-ae89-39b039434444",
    "eulaAccepted": true
  }]
}

При eulaAccepted: true сервер:

  1. Сохраняет в профиле пользователя принятую версию EULA.
  2. Продолжает прерванную цепочку входа (создание сессии, формирование JWT).
  3. Возвращает ответ такой же по структуре, как успешный login/create — с data.token и полями профиля.

Отклонение (пользователь не согласился):

{
  "object": {"name": "login"},
  "command": {"name": "eula.resolve"},
  "data": [{
    "pendingID": "e414c5c7-9b2f-48e0-ae89-39b039434444",
    "eulaAccepted": false
  }]
}

При eulaAccepted: false:

  • токен не выдается;
  • данные профиля и token в ответ не приходят;
  • для доступа к API нужен новый цикл с login/create;
  • тело ответа содержит только служебные поля и не включает данные профиля или токен (поле data — пустой массив, полей профиля и token нет):
{ "mode":"online", "status":200, "message":"", "data":[] }

Пример curl (принятие):

curl -s -X POST 'https://<host>/v1/api/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "object": {"name": "login"},
    "command": {"name": "eula.resolve"},
    "data": [{
      "pendingID": "e414c5c7-9b2f-48e0-ae89-39b039434444",
      "eulaAccepted": true
    }]
  }'

Справочник: login/eula.resolve.

Возможные ошибки:

Ситуация Сообщение (публичная часть)
Не передан pendingID Не передан идентификатор pending
Нет отложенной записи / истек срок (15 мин) Запись EULA не найдена или истекла

 

Важно: pendingID действует 15 минут с момента выдачи. При истечении этого срока или перезапуске сервера запись теряется. В этом случае необходимо заново выполнить команду login/create.

Сводная таблица команд EULA

Шаг Команда Authorization Что возвращает
1 login/create нет pendingID или сразу token
2 login/eula.get_text нет data.eulaText
3 login/eula.resolve нет при принятии — data.token как при успешном входе

 

Повторное принятие после обновления EULA

Администратор может опубликовать новую версию соглашения в метаданных. При следующем login/create пользователи, принявшие старую версию, снова получат eulaAcceptancePending и пройдут шаги eula.get_texteula.resolve.

Использование токена

Поле data.token (из login/create или из eula.resolve при принятии) — это JWT-маркер сессии. Передавайте его в каждом защищенном запросе к API.

Заголовок запроса:

Authorization: Bearer <значение data.token>
Content-Type: application/json

Префикс Bearer и пробел перед токеном обязательны. Токен передается как строка, без кавычек.

Токен привязан к серверной сессии. При завершении сеанса (выход, таймаут, административное завершение) API вернет сообщение об ошибке, например: «Сеанс пользователя завершен» или «Необходимо повторно пройти аутентификацию». В этом случае выполните login/create заново.

Один токен предназначен для серии запросов. Не вызывайте команду входа перед каждой командой.

Query-параметр (редко):

  • auth_token=<token> в URL — для открытия отчета в браузере (автоэкспорт). Для JSON API — только Authorization: Bearer <token>.

Команды без токена

Следующие команды не требуют заголовка Authorization:

Команда Объект Назначение
create login Вход, начало сценария
eula.get_text login Текст соглашения по pendingID
eula.resolve login Принятие/отказ от EULA, завершение входа
bind_ids login Связывание внешнего ID (может вернуть ветку EULA)
list.common.settings login Настройки до входа
echo, health check Проверка доступности (GET/HEAD)

 

Вызов других команд API

После получения data.token все остальные команды вызываются по единому шаблону:

POST https://<host>/v1/api/<object>
Authorization: Bearer <token>
Content-Type: application/json

{
  "object": {"name": "<object>"},
  "command": {"name": "<command>"},
  "data": [{ ... }]
}
  • <object> в URL и в object.name совпадают (users, datasources, reports, …);
  • command.name — имя команды из справочника API;
  • data — массив объектов. Для одной операции достаточно одного элемента.

Пример — справочник ролей:

curl -s -X POST 'https://<host>/v1/api/users' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{
    "object": {"name": "users"},
    "command": {"name": "role.list"}
  }'

Пример — список источников:

curl -s -X POST 'https://<host>/v1/api/datasources' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{
    "object": {"name": "datasources"},
    "command": {"name": "list"}
  }'

Пример — создание источника:

curl -s -X POST 'https://<host>/v1/api/datasources' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{
    "object": {"name": "datasources"},
    "command": {"name": "create"},
    "data": [{
      "parentID": 20,
      "caption": "Мой источник",
      "name": "my_datasource"
    }]
  }'

Документация: datasources/create.

Сквозной пример (вход + команда):

# 1. Вход
RESP=$(curl -s -X POST 'https://<host>/v1/api/login' \
  -H 'Content-Type: application/json' \
  -d '{"object":{"name":"login"},"command":{"name":"create"},"data":[{"username":"admin","password":"***","pcid":1}]}')

# 2. Если нужен EULA — обработать pendingID (get_text → resolve), иначе:
TOKEN=$(echo "$RESP" | jq -r '.data.token')

# 3. Команда с токеном
curl -s -X POST 'https://<host>/v1/api/users' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"object":{"name":"users"},"command":{"name":"role.list"}}'
Связи контента