Авторизация через внешние сервисы

Condo API может встраиваться в сторонние поверхности и использоваться в качестве бэкенда в мобильных, веб и десктопных приложениях. Для таких интеграций часто требуется уметь авторизовываться в Condo API через внешний сервис партнёра.
Condo позволяет добавить данную авторизацию, используя протокол Open ID Connect

Авторизация в Condo через OIDC

Чтобы добавить авторизацию в Condo через ваш сервис с использованием OIDC, вам необходимо реализовать данный протокол на стороне своего бэкенда, став тем самым провайдером OIDC-авторизации для Condo API.
После чего необходимо передать команде Condo следующий набор параметров:
Название параметраОписание параметраПример
userInfoURLAPI-эндпоинт вашего сервера, который по полученному токену будет отдавать информацию о пользователеhttps://my-app.example.com/api/oidc/me

Как работает авторизация через OIDC

После регистрации вас в качестве провайдера авторизации, мы выдадим вам имя провайдера (provider), использующееся в эндпоинтах авторизации и идентификатор клиента (client_id).
После чего начать процесс авторизации можно, перейдя на endpoint вида /api/auth/:provider?user_type=...&client_id=...&access_token=...
Данный эндпоинт обработает ваш запрос и перенаправит вас (совершив redirect) на /api/auth/:provider/callback, где будет происходить непосредственная авторизация. В случае успешной авторизации, callback-эндпоинт перенаправит вас на /, выставив заголовок set-cookie с параметром keystone.sid, необходимым для выполнения дальнейших запросов в API.

Про access_token

Для начала авторизации помимо client_id и user_type, вы должны передать нам OIDC access_token от вашего сервиса. Используя его, Condo API выполнит запрос на предоставленный вами userInfoURL для получения информации о пользователе. Данный токен выписывается вашим сервисом непосредственно перед авторизацией. Он может быть короткоживущим и с минимальными правами доступа, необходимыми для получения информации о текущем пользователе.

Структура userInfo

Особое внимание стоит обратить на эндпоинт userInfoURL, так как именно он отвечает за создание и синхронизацию пользователей в платформе Condo с сервисом партнёра.
В минимальном варианте для корректной привязки пользователя userInfo должен возвращать идентификатор пользователя в вашем сервисе, его номер телефона и имя пользователя. Email может быть указан дополнительно при наличии.
json
{ "sub": "cmd30383l000q07jy8cqo2zd7", "phone_number": "+79990001234", "name": "Иван Петров" }
json
{ "sub": "cmd30383l000q07jy8cqo2zd7", "phone_number": "+79990001234", "phone_number_verified": true, "email": "i.petrov@example.com", "email_verified": false, "name": "Иван Петров" }

Про верификацию телефона

При первой авторизации пользователя, Condo API потребует дополнительного подтверждения номера телефона, предоставленного вами из userInfoURL. В этом случае /api/auth/:provider/callback вернёт соответствующую ошибку:
Пример ответа с ошибкой
Чтобы верифицировать телефон, необходимо выполнить 2 анонимных GraphQL-запроса в Condo GraphQL API: startConfirmPhoneAction для отправки СМС-кода подтверждения на указанный телефон и completeConfirmPhoneAction для верификации телефона полученным кодом.
После чего необходимо повторить запрос на авторизацию, дополнительно передав параметр confirm_phone_action_token, полученный из мутации startConfirmPhoneAction и подтвержденный в мутации completeConfirmPhoneAction

Пробуем пройти процесс авторизации "от и до"

Для всех запросов в примере ниже будут использоваться:
  • test-sdk - выданный provider name
  • test-client-id - выданный client_id
Для старта авторизации получаем OIDC-токен вашего сервиса и идем на endpoint /api/auth/test-sdk?user_type=resident&client_id=test-client-id&access_token=..., после чего получаем редирект на callback:
Пример ответа с редиректом
Переходим на callback и получаем ошибку о том, что необходимо подтвердить телефон:
Пример ответа с ошибкой
Выполняем GraphQL-запрос startConfirmPhoneAction для отправки кода подтверждения и получаем confirm_phone_action_token:
Пример запроса СМС-кода
Выполняем GraphQL-запрос completeConfirmPhoneAction для подтверждения телефона:
Пример подтверждения телефона
Повторно переходим на /api/auth/test-sdk?user_type=resident&client_id=test-client-id&access_token=...&confirm_phone_action_token=cp:18f854bd-8c06-4c98-bdcb-5b01f61ea383, получаем redirect на callback, а затем на /.
Пример получения авторизации пользователя в куке keystone.sid
В целях безопасности мы передаем авторизационный токен пользователя не в открытом виде, а в виде куки keystone.sid. Чтобы получить из неё токен, необходимо сначала декодировать значение с помощью decodeURIComponent, а затем убрать префикс s:. После чего полученный токен можно использовать в качестве Bearer-токена в последующих запросах:
Пример декодирования значения keystone.sid

Особенности браузерной реализации

При реализации данной интеграции в браузерной среде вы можете столкнуться со следующими проблемами:
  • Политика CORS не позволяет вам выполнить GraphQL-запросы со стороннего домена;
  • Заголовок set-cookie недоступен браузерному клиенту.
Для их решения рекомендуется проксировать GraphQL-эндпоинт /admin/api, а также полученные вами /api/auth/:provider и /api/auth/:provider/callback через ваш бэкенд.