Кнопка авторизации

Введение

RegosOAuthSDK — это легковесная JavaScript-библиотека для простой интеграции кнопки "Войти через REGOS" на ваш сайт или приложение с использованием OAuth 2.0 и OpenID Connect. После успешной авторизации пользователя кнопка автоматически заменяется круглым аватаром с выпадающим меню, содержащим информацию о профиле и опции управления.

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

Возможности библиотеки

  • Настраиваемый внешний вид кнопки: Размер (s/m/l), тема (light/dark), тип (text/icon-text/icon), тип текста (full/short), радиус скругления.
  • Мультиязычность: Поддержка русского (ru), английского (en) и узбекского (uz) языков для текстов кнопки и меню.
  • Без зависимостей: Работает на чистом JavaScript, автоматически подгружает стили.
  • Безопасность: Использует Authorization Code Flow с PKCE для защиты от атак.
  • Автоматическая обработка: Проверка токенов при инициализации, отображение профиля, если пользователь уже авторизован.
  • Тихая авторизация (silent): Автоматический вход без попапа через iframe, если сессия активна на сервере REGOS.
  • API на основе Promise: Легкий вызов методов для авторизации.
  • Обработка ошибок: Callbacks для данных, выхода и ошибок; поддержка debug-режима для логов.
  • Обработка токенов: Хранение в localStorage (персистентно, работает в PWA и нескольких вкладках без синхронизации через storage events).

Важно: Зарегистрируйте приложение в REGOS для получения clientId. Redirect URI должен совпадать с зарегистрированным.

Сервер использует scopes, указанные при регистрации клиента.

Внешний вид блока авторизации

Пример темной кнопки:

button

Пример светлой кнопки:

button2

Отображение профиля после успешной авторизации:

menu

Установка

Подключите библиотеку через CDN:

<script src="https://auth.regos.uz/widget/regos-oauth-sdk.js"></script>

Создайте контейнер для кнопки:

Добавьте <div> с уникальным ID (по умолчанию "regos-login").

<div id="regos-login"></div>

Настройте страницу перенаправления (redirect URI):

Создайте файл (например, redirect.html) для обработки ответа в попап/iframe. Эта страница отправляет код авторизации обратно в основное окно и закрывается.

<!DOCTYPE html>
<html lang="ru">
<head>
    <title>REGOS Redirect</title>
</head>
<body>
    <script src="https://auth.regos.uz/widget/regos-redirect.js"></script>
</body>
</html>

Объяснение: regos-redirect.js парсит параметры URL (code, state, error), отправляет их через postMessage в родительское окно (или сохраняет в localStorage для redirect-flow) и перенаправляет на сохранённый returnUrl.

Быстрый старт

Инициализируйте SDK с помощью RegosOAuthSDK.initialize(config). Метод возвращает Promise, который разрешается после инициализации (без возвращаемых методов, так как все управление через callbacks и автоматическое).

При инициализации автоматически проверяются токены: если валидны, отображается профиль и вызывается onData(user, access_token); если silent: true — пытается тихая авторизация.

Пример базовой инициализации:

RegosOAuthSDK.initialize({
    clientId: 'regos_983436cgv2536fqvsac5623d78232dxfs',
    redirectUri: 'https://example.com/oauth/redirect.html',
    language: 'ru',
    buttonSize: 'm',
    buttonTheme: 'light',
    silent: false,
    buttonBorderRadius: 6,
    onData: (user, access_token) => {
        if (user) {
            console.log(`Пользователь авторизован: ${JSON.stringify(user)}`);
            console.log(`Access token: ${access_token}`);
        } else {
            console.log('Авторизация утрачена');
        }
    },
    onLogout: () => {
        console.log('Выход выполнен');
    },
    onError: (err) => {
        console.error(`Ошибка: ${err.message}`);
    },
    debug: false
})
.catch(err => console.error('Инициализация не удалась:', err));

Объяснение: Если токены уже есть и валидны, профиль отображается сразу, и вызывается onData с данными. Авторизация использует popup или redirect в зависимости от flow ('auto' — автоопределение по устройству).

Конструктор кнопки

Для удобной визуальной кастомизации кнопки "Войти через REGOS" без написания кода используйте онлайн-конструктор, доступный по адресу: https://docs.regos.uz/ru/sso/sso-button/constructor.

Подробное описание опций

Параметр Тип Обязательно Описание
clientId string Да ID приложения из REGOS.
redirectUri string Да URL страницы перенаправления (должен быть зарегистрирован в REGOS).
containerId string Нет ID контейнера для кнопки/профиля (по умолчанию 'regos-login').
buttonSize string Нет Размер кнопки: 's', 'm' (по умолчанию), 'l'.
buttonTheme string Нет Тема: 'light' (по умолчанию), 'dark'.
buttonBorderRadius number Нет Радиус скругления кнопки (число в пикселях, по умолчанию 4).
buttonType string Нет Тип кнопки: 'text' (только текст), 'icon-text' (иконка + текст, по умолчанию), 'icon' (только иконка).
buttonTextType string Нет Тип текста кнопки: 'full' (полный текст, по умолчанию), 'short' (короткий текст).
language string Нет Язык: 'ru' (по умолчанию), 'en', 'uz'.
flow string Нет Тип потока авторизации: 'auto' (автоопределение popup/redirect, по умолчанию), 'redirect' (всегда redirect).
onData function Да Callback для данных: получает объект пользователя (user) и access_token; null, null при потере авторизации.
onLogout function Нет Callback после выхода (локального).
onError function Нет Callback для ошибок (по умолчанию console.error).
silent boolean Нет Включить тихую авторизацию при инициализации (по умолчанию false).
debug boolean Нет Включить debug-логи в консоль (по умолчанию false).

Подробное описание колбэков

  • onData(user, access_token): Основной callback SDK, вызывается для уведомления о статусе авторизации.

    • Параметры:
    • user: Объект профиля пользователя (из /userinfo) или null, если авторизация утрачена.
    • access_token: Строка с токеном доступа или null.
    • Когда вызывается:
    • После успешного получения и кэширования профиля (при инициализации, входе, refresh).
    • При потере авторизации (токены невалидны, истекли, удалены, ошибка refresh).
    • При каждом обновлении access_token (refresh) — профиль запрашивается заново.
    • Особенности: Не вызывается повторно, если профиль не изменился и кэш свежий (TTL 60 сек). Если профиль не изменился, но токен обновлен, все равно вызывается с новыми данными.
    • Пример использования:
      onData: (user, access_token) => {
      if (user) {
          // Обновить UI с данными пользователя
          console.log('Авторизован:', user, access_token);
      } else {
          // Показать кнопку входа или редирект на login
          console.log('Не авторизован');
      }
      }
  • onLogout(): Callback после локального выхода.

    • Параметры: Нет.
    • Когда вызывается: При клике на кнопку "Logout" в меню профиля (локально очищает токены, вызывает onData(null, null) и этот callback).
    • Особенности: Не вызывает серверный logout; только локальная очистка. Для полного выхода пользователь может использовать ссылку в меню.
    • Пример использования:
      onLogout: () => {
      console.log('Пользователь вышел');
      // Дополнительные действия: редирект, очистка состояния
      }
  • onError(error): Callback для обработки ошибок.

    • Параметры:
    • error: Объект Error с описанием (message).
    • Когда вызывается: При любой ошибке (ошибка токена, запроса профиля, refresh, авторизации и т.д.). После ошибки часто вызывается onData(null, null).
    • Особенности: По умолчанию console.error; рекомендуется переопределить для UI-уведомлений.
    • Пример использования:
      onError: (err) => {
      alert(`Ошибка: ${err.message}`);
      }

Сценарии работы

  1. Проверка токенов: При инициализации SDK проверяет наличие и валидность токенов в localStorage.
  2. Если токены валидны: Запрашивает профиль (кэш в памяти 60 сек), отображает аватар с меню, вызывает onData(user, access_token).
  3. Если silent: true: Пытается тихая авторизация через iframe. Успех — как выше; неудача — рендер кнопки и onData(null, null).
  4. Иначе: Рендерится кнопка входа, onData(null, null).
  5. При нажатии на кнопку: Запускается авторизация: popup или redirect в зависимости от flow ('auto' — автоопределение по устройству).
  6. После успешной авторизации: Кнопка заменяется аватаром. Клик по аватару открывает меню с именем, email и ссылками (profile, edit, logout на auth.regos.uz). Меню закрывается кликом вне области. Вызывается onData с данными.
  7. Logout: Клик на "Logout" в меню: локально очищает токены, возвращает кнопку, вызывает onData(null, null) и onLogout.
  8. Refresh: Автоматически при запросе профиля, если access_token invalid (401). При ошибке — onData(null, null) и onError.

Внешний вид кнопки и аватара: Кнопка рендерится с иконкой (опционально), текстом (в зависимости от buttonType и buttonTextType), применяются классы для темы и размера. Аватар — круглый элемент с изображением или инициалами, клик toggles меню.

Тихая авторизация (Silent Authentication)

Тихая авторизация позволяет автоматически войти пользователя без попапа/redirect, если сессия REGOS активна. Реализовано через скрытый iframe с prompt=none.

  • Включение: Установите silent: true в config. Запускается только при инициализации (ручного вызова нет).
  • Процесс: Iframe загружает auth URL с prompt=none, получает code через postMessage, обменивает на токены, запрашивает профиль, вызывает onData.
  • Ограничения: Требует активной сессии на сервере; не работает в cross-origin изоляции (Safari). Таймаут: 10 сек.
  • Отладка: С debug: true логируют попытки и ошибки (e.g., "Silent auth failed: login_required").

Пример с silent:

RegosOAuthSDK.initialize({
    clientId: 'your_client_id',
    redirectUri: 'https://your-site.com/redirect.html',
    silent: true,
    debug: true,
    onData: (user, token) => console.log(user ? 'Silent success' : 'Silent failed')
})
.catch(err => console.error('Silent auth ошибка:', err));

Интерфейс после авторизации

  • Кнопка заменяется аватаром.
  • Клик по аватару: выпадающее меню с данными профиля.
  • Локальный logout через кнопку в меню: очищает токены, возвращает кнопку, вызывает onData(null, null) и onLogout.

Обработка ошибок

  • Callbacks: onError для сетевых/авторизационных ошибок (e.g., invalid_token), затем часто onData(null, null).
  • Promise rejections: В initialize() — используйте catch для обработки ошибок инициализации.
  • Redirect-страница: Отображает ошибки (e.g., "REGOS authorization error: access_denied").
  • Silent ошибки: Логируются (debug: true), fallback на кнопку и onData(null, null).
  • Общие случаи: Popup закрыт — fallback на redirect; нет crypto API — throw error.

Все ошибки важно обрабатывать в onError и catch блоках.

Пример обработки:

onError: (err) => alert(`Ошибка авторизации: ${err.message}`)

Примеры интеграции

Vanilla JS с кастомизацией

<!DOCTYPE html>
<html lang="ru">
<head>
    <title>REGOS Login</title>
</head>
<body>
    <div id="regos-login"></div>
    <script src="https://auth.regos.uz/widget/regos-oauth-sdk.js"></script>
    <script>
        RegosOAuthSDK.initialize({
            clientId: 'your_client_id',
            redirectUri: 'redirect.html',
            buttonSize: 'l',
            buttonType: 'icon-text',
            buttonTextType: 'short',
            buttonBorderRadius: 14,
            language: 'en',
            flow: 'auto',
            silent: true,
            onData: (user, token) => console.log(user, token)
        });
    </script>
</body>
</html>

Интеграция в React

// React example
useEffect(() => {
    RegosOAuthSDK.initialize({ /* config */ })
        .catch(err => console.error(err));
}, []);

Пример с buttonType

buttonType: "icon-text", // варианты: "text", "icon-text", "icon"

Рекомендации

  • Хранение: localStorage для персистентности (работает между вкладками без мгновенной синхронизации; изменения видны после refresh или реинициализации).
  • UX: Добавьте лоадер во время авторизации; используйте onData для обновления UI после входа/выхода.
  • Безопасность: Не храните токены в незащищённом месте; используйте HTTPS; обрабатывайте CSRF через state.
  • Кэширование профиля: Только в памяти (TTL 60 сек), не в localStorage; запрашивается заново при refresh или устаревании.