Skip to main content
Для не-.NET стеков Veriqa — обычный OpenID Connect провайдер. Пакета Veriqa для Python нет и не требуется: вы подключаете стандартный OIDC-клиент, а всю специфику (страница входа, QR, подтверждение в мессенджере) Veriqa выполняет на своей стороне.
Один код, любое развёртывание. Приложению не важно, где работает Veriqa — в облаке Veriqa, в вашем контейнере Docker или службой (systemd либо служба Windows) на вашей машине. Варианты различаются только адресом issuer’а и тем, где заведён клиент; код приложения ниже одинаков для всех, а переключение сводится к одному server_metadata_url.

1. Установите библиотеку

Рекомендуемая библиотека — Authlib (актуальная линия 1.8.x):
Authlib не тянет за собой ни веб-фреймворк, ни HTTP-клиент. flask — фреймворк, на котором построен пример ниже; requests — то, на чём построены интеграции Authlib с Flask и Django, а у Starlette и FastAPI вместо него httpx, так что ставьте нужный вашему фреймворку. Без любого из этих пакетов первый же запуск падает на блоке импортов в начале app.py с ModuleNotFoundError — ещё до обращения к Veriqa. Требуется Python 3.10 или новее — это минимум, объявленный пакетом. Готовые интеграции есть для Flask, Django, Starlette и FastAPI; ниже показан Flask, у остальных тот же реестр OAuth и те же вызовы.

2. Заведите клиента на стороне Veriqa

Veriqa Cloud сейчас недоступен — строки про облако описывают контракт его API. Используйте self-hosted; подробности — в Veriqa Cloud.
У self-hosted две поставки, и для этой страницы они равнозначны. Сервер работает в контейнере Docker — быстрый старт self-hosted — либо ставится из архива юнитом systemd или службой Windows, без Docker и без рантайма .NET на машине — установка службой ОС. Выбор определяет способ поставки сервера, а не регистрацию клиента, адрес issuer’а и код ниже. Секрет не обязателен. Минимальный рабочий набор — issuer, client_id, redirect_uri: public-клиент с PKCE, и это дефолт облака. Confidential-клиент нужен, только если вы хотите аутентифицировать серверное приложение секретом; в облаке секрет выпускается отдельным явным действием на экране Applications и показывается один раз. redirect_uri сверяется точным совпадением — wildcard не поддерживаются. Регистрируйте ровно тот URL, который отдаёт ваш маршрут callback. Для примера на Flask ниже, запущенного как в шаге 7, это http://127.0.0.1:5000/authorize — регистрируйте ровно его и открывайте приложение в той же форме хоста (127.0.0.1, а не localhost): URL callback’а строит url_for(..., _external=True) из хоста входящего запроса, а сверка на стороне Veriqa буквальная.

3. Зарегистрируйте провайдера

server_metadata_url включает discovery: Authlib сам читает /.well-known/openid-configuration и находит остальные эндпоинты. Значения код берёт из окружения, поэтому задайте их в той оболочке, из которой будете запускать приложение. Первые три — то, что вы получили на шаге 2, четвёртая — ваша собственная:
FLASK_SECRET_KEY Veriqa не выдаёт — это ваша произвольная случайная строка, ключ, которым Flask подписывает cookie сессии. В систему контроля версий он не попадает, и в каждом окружении значение своё. Варианту public VERIQA_CLIENT_SECRET не нужен: у public-клиента секрета нет вовсе. Не задать любую из переменных, которые читает выбранный вариант, — и первый же запуск падает с KeyError ещё на импорте app.py, до первого маршрута. Каждый вариант ниже — целиком «голова» app.py: приложение Flask, секрет сессии, нужный Authlib, и регистрация провайдера. Маршруты шага 4 кладутся в этот же файл, ниже.
PKCE в Authlib не включается сам — в отличие от способа аутентификации. Метод аутентификации клиента выводится автоматически: есть client_secret — client_secret_basic, нет — none, то есть public-клиент получается просто отсутствием секрета. А вот PKCE — независимый переключатель: без code_challenge_method в client_kwargs public-клиент пойдёт без PKCE. Задавайте его явно.
Переключение между вариантами — облако, Docker, служба ОС — правка одного VERIQA_ISSUER.

4. Опишите маршруты входа

app.py
authorize_access_token() сам обменивает код на токены и разбирает id_token — готовые claims лежат в token["userinfo"], отдельно вызывать userinfo-эндпоинт не нужно. code_verifier для PKCE библиотека генерирует и хранит сама, руками его передавать не требуется. Между /login и /authorize работает Veriqa: пользователь видит страницу входа с QR и списком каналов и подтверждает вход в мессенджере на телефоне. / — то, куда браузер попадает в конце: пока в сессии пусто, маршрут отправляет на /login, а после успешного входа показывает, что в неё положено, — словарь, возвращённый из view Flask, сериализуется в JSON, так что результат виден без единого шаблона.

5. Прочитайте claims

Базовый набор Veriqa кладёт в токены сама: Claims канала выдаются только по scope channel: Без запрошенного scope channel эти два claim не попадают ни в один токен — и, следовательно, не появляются в ответе userinfo, который зеркалит access_token. Именно по ним приложение различает привязанные каналы, поэтому для сценария привязки аккаунта scope обязателен.

6. Ограничьте вход конкретным каналом

Стандартный OIDC-параметр acr_values формата channel:{тип} сужает выбор на странице входа. Дополнительные именованные аргументы authorize_redirect уходят в authorize-запрос как есть:
Несколько значений через пробел (channel:telegram channel:whatsapp) — пользователь выбирает из перечисленных. Без параметра доступны все включённые на сервере каналы.

7. Контрольная точка

Запустите приложение из каталога, где лежит app.py, в той оболочке, где экспортированы переменные шага 3:
Flask отдаёт его на http://127.0.0.1:5000 — именно из этого адреса строится redirect_uri, зарегистрированный на шаге 2.
1

Проверьте discovery

curl $VERIQA_ISSUER/.well-known/openid-configuration возвращает метаданные с https-URL.
2

Запустите вход

Откройте http://127.0.0.1:5000/login — браузер должен уйти на страницу Veriqa с QR и каналами.
3

Подтвердите на телефоне

Подтвердите запрос в доверенном канале; браузер вернётся на ваш маршрут /authorize, а тот перенаправит его на /.
4

Проверьте claims

/ показывает сессию в виде JSON: sub заполнен, а channel_type несёт канал, которым подтверждён вход, — он остаётся null, если scope channel не запрашивался.

Дальше

Сценарии интеграции

Привязка канала, повторное подтверждение и подтверждение действия — на уровне HTTP.

Быстрый старт: self-hosted

Развернуть свой issuer в Docker.

Установка службой ОС

Тот же issuer без Docker — systemd или служба Windows, из архива.

OIDC + Veriqa: разбор

Где Veriqa встаёт в стандартный поток.

Hardening к продакшну

Что проверить перед выпуском.