АвторизацияOAuthTelegram

Вход через Яндекс ID, VK ID и Telegram: как подключить и на чём спотыкаются

6 мин чтения

Пользователям в России привычнее входить через Яндекс, VK или Telegram. Подключить их сложнее, чем Google: у каждого свои особенности. Ниже всё по порядку.

Общая схема

Вход через внешний сервис устроен одинаково:

  1. Приложение отправляет пользователя на страницу провайдера с client_id, redirect_uri и state.
  2. Пользователь подтверждает вход, провайдер возвращает его на redirect_uri с одноразовым code.
  3. Сервер приложения обменивает code на токен доступа.
  4. По токену приложение получает данные пользователя: идентификатор, имя, email.

Для защиты обмена кода используется PKCE: приложение генерирует случайный code_verifier, а в первый запрос отправляет его хеш code_challenge. Перехваченный код без code_verifier бесполезен.

Если провайдер поддерживает OpenID Connect, шаг 4 упрощается: данные пользователя приходят сразу в подписанном id_token, а адреса всех эндпоинтов публикуются в документе .well-known/openid-configuration. Тогда библиотеке достаточно одного адреса провайдера.

Яндекс ID

Регистрация. Приложение создаётся на oauth.yandex.ru: платформа «Веб-сервисы», Redirect URI, доступы к данным (логин, имя, email, аватар).

Эндпоинты:

авторизация:  https://oauth.yandex.ru/authorize
токен:        https://oauth.yandex.ru/token
пользователь: https://login.yandex.ru/info?format=json

Подводные камни:

  • Документа OpenID Connect discovery нет. Подключение только как обычный OAuth2, с ручным указанием трёх адресов.
  • Поля ответа нестандартные: идентификатор в id, email в default_email, а не sub и email. Универсальным OAuth2-клиентам нужно настроить сопоставление полей.
  • Email приходит, только если доступ к нему отмечен при регистрации приложения.

VK ID

Регистрация. Приложение создаётся в кабинете VK ID для бизнеса: платформа «Веб-сайт», базовый домен, доверенный Redirect URL.

VK ID работает по OAuth 2.1 с обязательным PKCE. На этом сходство со стандартом заканчивается.

Подводные камни:

  • device_id. Вместе с code на Redirect URL приходит параметр device_id. Без него обмен кода на токен не работает. Стандартные OAuth-клиенты этот параметр не знают и не передают.
  • Данные пользователя только POST-запросом. Токен передаётся в теле запроса вместе с client_id, а не в заголовке Authorization: Bearer, как ожидают библиотеки.
  • Новые и старые приложения. У VK два API входа: старый oauth.vk.com и новый VK ID. Многие готовые провайдеры в библиотеках написаны под старый. Новые приложения настраиваются под VK ID.

Обмен кода выглядит так:

curl -X POST https://id.vk.ru/oauth2/auth \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d code_verifier="$CODE_VERIFIER" \
  -d client_id="$CLIENT_ID" \
  -d device_id="$DEVICE_ID" \
  -d redirect_uri="$REDIRECT_URI" \
  -d state="$STATE"

Из-за этих отличий VK ID не подключается через универсальные провайдеры OAuth2, в том числе через настройку произвольного провайдера в Supabase Auth. Нужен отдельный провайдер, написанный именно под VK ID: такие есть для Keycloak, Better Auth, Laravel Socialite и OmniAuth.

Telegram

Telegram долго предлагал только виджет входа с подписью данных через хеш токена бота. Теперь у него есть полноценный OpenID Connect.

Регистрация. В @BotFather выбирается бот, раздел Login Widget, туда вносятся разрешённые адреса сайта и Redirect URL. Там же BotFather показывает Client ID и Client Secret. Client ID совпадает с идентификатором бота.

Адрес провайдера: https://oauth.telegram.org. Discovery-документ опубликован, поэтому подходит любая OIDC-библиотека.

Доступные данные (scopes):

  • openid: идентификатор пользователя;
  • profile: имя, имя пользователя, фото;
  • phone: подтверждённый номер телефона, с согласия пользователя;
  • telegram:bot_access: разрешение боту писать пользователю после входа.

Подводный камень: email Telegram не передаёт. Если в приложении email обязателен, его придётся запросить отдельно после входа. В Supabase Auth для таких провайдеров есть настройка email_optional.

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

Яндекс IDVK IDTelegram
ПротоколOAuth2OAuth 2.1 с отличиямиOpenID Connect
Discoveryнетнетесть
PKCEподдерживаетсяобязателенподдерживается
Emailпри доступе к немупри scope emailнет
Универсальный OAuth2-клиентда, с сопоставлением полейнетда

Как подключить все три сразу

Библиотека в коде. Better Auth поддерживает Яндекс и VK ID отдельными провайдерами, Telegram подключается как обычный OIDC. Подходит, если бэкенд свой и авторизация живёт в нём.

Сервер авторизации. Keycloak с открытым модулем российских провайдеров (keycloak-russian-providers) поддерживает Яндекс, VK ID, Mail.ru и Одноклассники, Telegram добавляется как OIDC-провайдер. Сам Keycloak при этом выступает одним стандартным OIDC-провайдером для приложений. Так российские входы попадают в Supabase, PocketBase или любой фреймворк одной настройкой. Цена вопроса: Keycloak требует около 1 GB памяти и регулярных обновлений.

Готовый сервис. Тот же сервер авторизации, но эксплуатация на стороне провайдера.

В любом варианте приложения у Яндекса, VK и в BotFather регистрирует владелец сайта: ключи принадлежат ему, и провайдеры требуют подтверждать домен.

Читать дальше