Вход через 15Reg ID
Добавьте на свой сайт кнопку «Войти через 15reg». Пользователь входит в знакомый аккаунт, а ваш сайт получает подтверждение личности.
- Пользователь нажимает «Войти через 15reg».
- На id.15reg.ru входит и разрешает передать выбранные данные.
- Сайт получает одноразовый код, проверяет ответ и открывает свою сессию.
Что получит сайт
Всегда — постоянный идентификатор аккаунта. С разрешением profile — имя и имя пользователя; с email — почту и отметку о её подтверждении.
Что остаётся в 15reg
Пароль, сообщения, контакты и другие данные соцсети не передаются. Права и заказы внешнего проекта остаются в его собственной базе.
Самый короткий путь
Зарегистрируйте проект, добавьте точный адрес возврата и настройте свою библиотеку OpenID Connect: адрес провайдера https://id.15reg.ru, ID клиента и PKCE S256. Начните с openid.
Кабинет 15Reg ID
Проекты и разрешения вашего аккаунта.
Проверяем вход…
Интеграция для разработчика
1. Отдельный клиент для каждого приложения
- Войдите в кабинет 15Reg ID и создайте тестовый клиент. Для сайта выберите web, для Android — android. Клиент принадлежит текущему аккаунту.
- Укажите точный redirect URI, включая схему, порт и путь. Рабочее приложение требует HTTPS. HTTP разрешён только для loopback в тестовом web-клиенте. Маски, URL с паролем и фрагменты запрещены.
- Сохраните
client_idи issuerhttps://id.15reg.ru. Public-клиент с PKCE не получаетclient_secret. Зарегистрируйте отдельные клиенты для теста, production и Android. - При необходимости заранее зарегистрируйте точные post-logout redirect URI. Серверный back-channel callback требует HTTPS и включения его origin оператором ID.
Кабинет использует POST /v1/id/clients на основном домене с вашей обычной сессией и CSRF. Это пример тела, а не публичная регистрация без авторизации:
{
"name": "Мой проект — тест",
"environment": "test",
"platform": "web",
"redirectUris": [
"http://127.0.0.1:8080/callback"
],
"postLogoutRedirectUris": []
}Для серверного клиента API также принимает publicJwks и использует private_key_jwt. Передавайте только публичную часть ключа. Закрытый ключ остаётся на сервере вашего проекта. Среда test меняет регистрацию клиента и допустимые callback, но использует общие аккаунты ID: создайте отдельные тестовые аккаунты.
2. Authorization Code + PKCE S256
Получайте endpoints и JWKS через OpenID Connect discovery. Используйте поддерживаемую OIDC-библиотеку. Встроенная регистрация клиентов, implicit flow и password grant недоступны.
- Для каждого входа создайте новые state, nonce и PKCE verifier. Сохраните одноразовый запрос со сроком и привязкой к браузеру.
- Откройте authorization URL. ID предлагает вход, продолжение с известным аккаунтом, смену аккаунта и согласие на конкретные scopes.
- На callback проверьте state, браузерную привязку и срок. Атомарно заберите одноразовый запрос, затем обменяйте code с исходным verifier.
- Проверьте подпись JWT через JWKS, точные issuer и audience, nonce и время. Создайте собственную сессию проекта, используя идентичность
iss + sub.
Фрагменты ниже показывают операции SDK. Полный пример с PostgreSQL, сессией браузера и одноразовым flow находится в apps/id-example релизного исходного кода.
import * as oidc from 'openid-client'; // 6.8.9, Node 24
const config = await oidc.discovery(
new URL('https://id.15reg.ru'), process.env.ID_CLIENT_ID,
{ token_endpoint_auth_method: 'none' }, oidc.None()
);
oidc.enableNonRepudiationChecks(config);
const state = oidc.randomState();
const nonce = oidc.randomNonce();
const verifier = oidc.randomPKCECodeVerifier();
const url = oidc.buildAuthorizationUrl(config, {
response_type: 'code', scope: 'openid profile',
redirect_uri: 'https://project.example/callback',
state, nonce,
code_challenge: await oidc.calculatePKCECodeChallenge(verifier),
code_challenge_method: 'S256'
});
// Сначала сохраните state, nonce, verifier и срок 10 минут
// в серверной БД с привязкой к браузерной сессии.
// Затем отправьте браузер на url.href.// flow загружен по state и привязан к той же браузерной сессии.
// Атомарно пометьте его использованным ДО обмена кода.
const tokens = await oidc.authorizationCodeGrant(config, callbackUrl, {
pkceCodeVerifier: flow.verifier,
expectedState: flow.state,
expectedNonce: flow.nonce,
idTokenExpected: true
});
const claims = tokens.claims();
if (!claims?.sub || claims.iss !== 'https://id.15reg.ru') {
throw new Error('Invalid identity');
}
// Найдите связь по (claims.iss, claims.sub), затем создайте
// собственную сессию проекта. Email для объединения не используйте.
// Не печатайте callbackUrl, tokens или flow в лог.| Элемент | Назначение | Ограничение |
|---|---|---|
openid | Стабильный subject существующего аккаунта | Обязателен для OIDC |
profile | Имя и username | После согласия |
email | Адрес и фактический email_verified | Не основание для автопривязки |
offline_access | Refresh token | До 30 дней; ротация при каждом использовании |
| Code / interaction | Одноразовый обмен / экран подтверждения | 60 секунд / 10 минут |
| ID token / access token | Подтверждение входа / UserInfo | 5 минут |
Согласие на прежние scopes может использоваться повторно. Новые права требуют нового подтверждения. ID не выдаёт историю переписки или административную роль проекта. ID token, токен бота и cookie социальной сети не заменяют друг друга.
3. Безопасно свяжите существующий аккаунт
Если в вашем проекте уже есть локальные пользователи, не ищите совпадение по email, имени или телефону. Пользователь сначала входит в нужный локальный аккаунт, повторно подтверждает его пароль, затем выбирает ID через новый вход с prompt=login. Callback должен вернуться в ту же локальную сессию.
Сохраняйте связь в транзакции с уникальным ограничением на пару issuer/subject. Если ID уже принадлежит другому локальному пользователю, отклоните привязку. Смена локальной сессии во время выбора ID, повторный callback и просроченный запрос также отклоняются. Роли не копируются из ID автоматически.
4. Различайте сессии, выход и отзыв
| Действие | Результат |
|---|---|
| Выйти из вашего проекта | Удаляется локальная сессия проекта. Сессия ID может сохраниться. |
| Выйти из центра ID | RP-initiated logout из discovery с подтверждением на ID-домене. Полный выход отзывает связанную ID-сессию и очищает её cookie. |
| Отозвать разрешение проекта | В кабинете ID удаляется согласие и связанные серверные артефакты. Новое обращение потребует входа и согласия. |
| Отключить клиент | Владелец запрещает новые входы и использование его серверных артефактов для всех пользователей этого клиента. |
| Отозвать устройство / сменить пароль | Применяется обычное управление сессиями 15reg. Связанные с отозванной сессией protocol artifacts перестают проходить серверную проверку. |
Cookie основной соцсети остаётся host-only. ID-домен создаёт отдельную host-only сессию через ту же проверку существующего аккаунта. Поэтому при первом посещении ID может потребоваться пароль; вход в Android сам по себе не создаёт сессию системного браузера.
Уже выданный автономный ID JWT действует до своего expiry. Для завершения сессий внешнего проекта поддерживается OIDC Back-Channel Logout: проверяйте подпись, issuer, audience, время, logout event, отсутствие nonce, sid/sub и одноразовый jti. Пример содержит такой обработчик. Доставка в недоступный проект не является гарантированным мгновенным выходом: сохраняйте ограниченный срок своих сессий и следите за ошибками callback.
5. Нативный Android без WebView
Отдельный проект apps/id-android-example использует AppAuth, системную Custom Tab, PKCE и Android Keystore. Он не содержит secret клиента и не заменяет основной APK 15reg. Сохранённый запрос переживает уничтожение процесса; ответ проверяется против исходного state, client ID и точного redirect.
- Зарегистрируйте отдельный android-клиент с HTTPS callback вида
https://ваш-проект/oauth/android/callback. - Опубликуйте на своём домене
/.well-known/assetlinks.jsonс package name и SHA-256 сертификата этой сборки. - В
apps/id-android-exampleвыполните сборку с реальными client ID и callback host. Для PowerShell используйте.\gradlew.bat. - На устройстве проверьте верификацию App Link, согласие, отмену, смену аккаунта, возврат после уничтожения процесса и повтор callback. Unit-тесты не заменяют проверку браузерного возврата.
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "ru.reg15.idexample",
"sha256_cert_fingerprints": [
"SHA-256 СЕРТИФИКАТА ИМЕННО ВАШЕЙ СБОРКИ"
]
}
}
]./gradlew testDebugUnitTest lintDebug assembleDebug \
-PID_CLIENT_ID=ваш_client_id -PID_CALLBACK_HOST=ваш-доменПример рассчитан на Android 9 и новее. Он запрашивает openid/profile и очищает локальное состояние по кнопке выхода; фоновое обновление токенов в этом примере не реализовано. В Windows устанавливайте PWA через браузер.
6. Запустите готовый внешний пример
# Из корня релизного исходного кода, Node 24:
pnpm install --frozen-lockfile
# Скопируйте apps/id-example/.env.example в .env этой же папки.
# Укажите отдельную БД, ID_CLIENT_ID, LOCAL_USERNAME,
# уникальный LOCAL_PASSWORD (минимум 16 символов).
pnpm --dir apps/id-example migrate
pnpm --dir apps/id-example test
pnpm --dir apps/id-example start
# Откройте http://127.0.0.1:8080; Ctrl+C завершает процесс.Ожидаемый результат: вход через ID → согласие → собственная сессия внешнего проекта. Затем выйдите только из проекта и войдите повторно: локальная запись должна остаться той же. Для проверки привязки сначала используйте локальную форму входа, повторите локальный пароль и выберите ID. После настройки удалите LOCAL_PASSWORD из .env; в базе остаётся Argon2-хеш.
Пример запускается на loopback и использует отдельную БД. Перед размещением вашего проекта добавьте его собственные лимиты входа, восстановление, аудит и резервирование. Не направляйте пример в production-базу социальной сети.
Ошибки и проверка перед запуском
| Ситуация | Действие клиента |
|---|---|
access_denied | Покажите отказ и кнопку возврата. Не запускайте новый вход автоматически. |
invalid_grant | Code/refresh истёк, использован или не подходит. Начните новый вход; не повторяйте одноразовый обмен. |
invalid_client / invalid_request | Проверьте регистрацию, точный redirect и PKCE. Не принимайте произвольный callback из запроса пользователя. |
| Неверные state, nonce, issuer, audience, подпись | Прервите вход. Не создавайте сессию даже при HTTP 200 от token endpoint. |
| Сеть пропала после обмена | Операция могла состояться. Закройте flow и предложите новый вход вместо автоматического повтора code. |
| Refresh использован повторно | Цепочка отзывается. Исключите параллельное обновление в своём хранилище. |
Проверьте успешный и повторный вход, отказ, истечение, неверный verifier/state/nonce, повтор callback, другой client ID, отзыв сессии, привязку существующего аккаунта и невозможность привязать чужой. Не сохраняйте пароли, токены или callback query в access logs, аналитике и отчётах об ошибках.