Многотенантная интеграция (единый вход)

Предисловие

Многотенантность — распространённый подход для любого облачного приложения. Стратегия единого экземпляра для разных организаций всегда эффективнее с точки зрения обслуживания и затрат.

Компонент Editor предназначен для помощи в создании и управлении визуальным представлением схемы рассадки. Этот документ охватывает все случаи, когда тикетинговая платформа предоставляет многотенантность, и желаемая модель интеграции должна поддерживать такой сценарий.

Цели

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

Тенанты могут быть представлены как некие организации или клиенты в терминах тикетингового ПО.

Интеграция

Определения

Здесь и далее мы будем использовать следующие термины:

  • Ticketing Platform - TP - платформа для интеграции
  • Seatmap.pro - SMP - платформа, состоящая из двух основных компонентов:
    • Editor - UI-приложение для редактирования схем
    • Booking - API-компонент платформы, обрабатывающий аутентификацию и управление организациями

Модель

Мы привязываем пользователей к конкретному тенанту, тем самым определяя некую область или ограничение для разделения доступа между двумя или более организациями.

model

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

Основной поток

Рассмотрим начальный сценарий, когда аутентифицированный в TP пользователь пытается открыть UI SMP Editor. Чтобы пропустить шаг аутентификации на стороне SMP, у пользователя должны быть токены аутентификации. Чтобы связать две платформы, нужно выполнить следующие шаги:

  1. Для синхронизации организаций TP определяет организацию текущего пользователя и проверяет, что она уже существует на стороне SMP Booking и имеет некий ID.
    • Если организация не существует на стороне SMP Booking, TP должна сначала создать её с помощью API управления организациями
  2. Когда id организации известен, TP готова запросить одноразовый код сессии с помощью метода autoLogin
  3. В результате autoLogin TP открывает UI SMP Editor с полученным кодом; Editor обменивает его на сессию при загрузке. Устаревшие интеграции могут вместо этого получить и передать token и refreshToken напрямую

sequence

Создание организации

Чтобы создать организацию программно, нужно вызвать management API на стороне SMP Booking:

POST /api/private/management/v2.0/organizations/ HTTP/1.1
Host: {BOOKING_HOST}
Content-Type: application/json
X-API-Key: {tenantToken}

{
    "name": "Organization Name",
    "email": "jd@seatmap.pro",
    "firstName": "John",
    "lastName": "Doe",
    "password": "{INITIAL_PASSWORD}",
    "autologinEnabled": true
}

Этот эндпоинт требует tenant token в заголовке X-API-Key; токен организации отклоняется. Ответ будет содержать созданную организацию с её ID, который понадобится для последующих операций. Укажите autologinEnabled: true, чтобы организация принимала запрос autologin, описанный ниже; если поле не передано, оно равно false.

Название организации и данные администратора передаются полями верхнего уровня одного объекта. email определяет учётную запись администратора организации, регистр букв не учитывается. Если ни одна учётная запись не использует этот email, создаётся новая с переданным паролем. Существующая учётная запись становится администратором, только если это единственная учётная запись с таким email, она состоит хотя бы в одной организации, все её организации принадлежат тенанту, которому принадлежит ваш X-API-Key, и у неё нет роли администратора платформы (super admin или global admin); она сохраняет свой пароль, а переданный password не применяется. Для любой другой существующей учётной записи запрос завершается ответом 409 Conflict с кодом ошибки ACCOUNT_EMAIL_IN_USE, и ничего не создаётся: используйте для этой организации другой email.

Запрос автоматического входа

Метод автоматического входа позволяет получить пользовательскую сессию. Сейчас это обрабатывается системой SMP Booking:

POST /api/public/v2.0/autologin/ HTTP/1.1
Host: {BOOKING_HOST}
Content-Type: application/json
Content-Length: 164

{
    "login": "jd@seatmap.pro",
    "firstName": "John",
    "lastName": "Doe",
    "token": "{PRIVATE_KEY}",
    "responseType": "code"
}

С "responseType": "code" (рекомендуется) ответ содержит одноразовый код сессии вместо токенов сессии. Код действителен для одного обмена и истекает через 60 секунд:

{
  "success": true,
  "code": "{ONE_TIME_CODE}",
  "expiresIn": 60
}

Если responseType не указан, ответ содержит токены сессии напрямую:

{
  "user": {
    // User information
  },
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Автоматический вход принимает только учётные записи организаций. Учётная запись с ролью администратора платформы (super admin или global admin) получает HTTP 403 и должна входить в Editor со своим паролем.

Открытие приложения Editor

С кодом сессии откройте приложение SMP Editor в iframe, добавив код как параметр URL ssoCode. Editor автоматически обменяет код на сессию при загрузке:

<iframe
  src="{EDITOR_HOST}/app/?ssoCode={ONE_TIME_CODE}"
  width="100%"
  height="800px"
  frameborder="0"
>
</iframe>

Запрашивайте новый код у эндпоинта autologin при каждом открытии Editor: код расходуется при первой загрузке и не может быть использован повторно.

Если вы использовали ответ с токенами по умолчанию, добавьте token и refreshToken как параметры URL:

<iframe
  src="{EDITOR_HOST}/app/?token={token}&refreshToken={refreshToken}"
  width="100%"
  height="800px"
  frameborder="0"
>
</iframe>
Пример

Допустим, вам нужно открыть Editor для конкретной схемы площадки по URL https://editor.seatmap.dev/app/venues/2/schemas/150, и ответ autologin содержал код k3P9wXbF2tR8yQ6mA1sD4gJ7hL0cV5nZ8xE2uT6iO4q.

Полный URL для использования в вашем iframe будет таким:

https://editor.seatmap.dev/app/venues/2/schemas/150?ssoCode=k3P9wXbF2tR8yQ6mA1sD4gJ7hL0cV5nZ8xE2uT6iO4q

А полная реализация iframe будет такой:

<iframe
  src="https://editor.seatmap.dev/app/venues/2/schemas/150?ssoCode=k3P9wXbF2tR8yQ6mA1sD4gJ7hL0cV5nZ8xE2uT6iO4q"
  width="100%"
  height="800px"
  frameborder="0"
>
</iframe>

Введите название функции, настройки, эндпоинта или метода SDK.