SDK для фронтенда
SDK Авторизы — JavaScript / TypeScript-библиотека для быстрой интеграции авторизации в веб-приложения.
SDK реализует OAuth 2.0 / OpenID Connect с Authorization Code Flow + PKCE и берет на себя работу с authentication flow, токенами и сессией.
SDK не зависит от React, Vue, Angular или другого фреймворка.
SDK не обязателен.
Авториза работает со стандартным OAuth 2.0 / OpenID Connect, поэтому вы можете использовать любую подходящую библиотеку вашего языка или фреймворка.
Если вы не хотите разбираться в деталях OIDC и хотите добавить авторизацию с минимальным количеством кода, рекомендуем SDK.
Если вы хотите интегрировать Авторизу напрямую через OIDC-библиотеку, смотрите Библиотеки OIDC.
Когда SDK подходит
SDK предназначен для браузерных JavaScript и TypeScript-приложений, которым нужно добавить вход пользователя без самостоятельной реализации OIDC callback, PKCE, проверки ID Token и обновления сессии.
SDK не является серверным middleware. Он выполняет authentication flow в браузере. Если обмен кода и хранение credentials должны происходить на backend, используйте OIDC-библиотеку для серверного приложения и тип Confidential вместо публикации secret в клиентском коде.
Модель работы
Создание экземпляра не выполняет сетевых запросов синхронно. После создания SDK асинхронно восстанавливает сессию и, если текущий URL является callback, обрабатывает ответ authorization server:
createAuthoriza(config)
|
v
isLoading = true
|
+--> восстановление сессии
|
+--> обработка callback, если это redirectUri
|
v
isLoading = false
|
v
auth.user / auth.isAuthenticated
Поэтому интерфейс не должен считать isAuthenticated === false окончательным
результатом, пока isLoading === true. Сначала покажите loading-состояние, затем
решайте, отображать ли форму входа или защищённую часть приложения.
Установка
Установите пакет @authoriza/sdk:
npm install @authoriza/sdk
SDK распространяется как ESM-пакет, не имеет runtime-зависимостей и содержит полные TypeScript-типы.
Быстрый старт
Создайте экземпляр SDK:
import { createAuthoriza } from '@authoriza/sdk';
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
});
Проверьте состояние авторизации:
auth.isAuthenticated; auth.user; auth.isLoading;
Запустите вход:
await auth.login();
Чтобы после входа открыть определённую страницу:
await auth.login({
redirectAfterLoginTo: '/dashboard',
});
После успешной авторизации можно получить access token:
const token = await auth.getAccessToken();
И использовать его для запросов к вашему API:
const response = await fetch('/api/profile', {
headers: {
Authorization: `Bearer ${token}`,
},
});
Для выхода из приложения:
await auth.logout();
Настройка
Для создания SDK используются следующие параметры:
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
});
clientId
Идентификатор подключения вашего веб-приложения в Авторизе.
Получить его можно в настройках проекта в личном кабинете Авторизы.
Для frontend-приложения используется тип подключения Public. client_secret
для SDK не требуется и не должен использоваться в браузере.
redirectUri
URL, на который Авториза вернёт браузер после авторизации.
Этот адрес должен быть зарегистрирован в настройках подключения.
redirectUri — это технический callback URL OIDC. Он не определяет страницу,
на которую пользователь попадёт после входа.
Например:
redirectUri: 'https://example.com/auth/callback'
Подробнее:
issuer
URL OIDC-сервера Авторизы.
Для production используется значение по умолчанию:
https://oidc.authoriza.ru/oidc
Обычно указывать issuer вручную не требуется.
При необходимости его можно изменить:
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
issuer: 'https://oidc.authoriza.ru/oidc',
});
scope
Определяет, какие данные и возможности приложение запрашивает при авторизации.
По умолчанию SDK использует:
['openid', 'profile', 'email', 'offline_access']
openid добавляется SDK автоматически, даже если он не указан явно.
| Scope | Назначение |
|---|---|
openid | Включает OpenID Connect и идентификацию пользователя |
profile | Данные профиля, например имя |
email | Email пользователя |
offline_access | Позволяет получить Refresh Token для автоматического продления сессии |
Если приложение должно автоматически обновлять access token и поддерживать
сессию без повторного входа пользователя, используется offline_access.
При необходимости scopes можно изменить:
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
scope: ['openid', 'profile', 'email'],
});
Запрашивайте только те scopes, которые действительно нужны приложению.
onError
onError позволяет получать ошибки, возникающие во время асинхронной обработки
authentication flow, например при обработке callback или обновлении токенов:
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
onError(error) {
console.error(error.code, error.message);
},
});
sessionStorage
По умолчанию SDK использует localStorage для хранения сессии.
При необходимости можно передать собственную реализацию хранилища:
import {
createAuthoriza,
type SessionStorage,
} from '@authoriza/sdk';
const storage: SessionStorage = {
async get() {
// вернуть Session | null
},
async set(session) {
// сохранить сессию
},
async clear() {
// удалить сессию
},
};
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
sessionStorage: storage,
});
Вход
Для запуска авторизации используйте:
await auth.login();
Метод перенаправит браузер на Авторизу.
До перенаправления SDK сохраняет данные незавершённого flow: state, nonce,
code_verifier и выбранный внутренний путь после входа. Эти данные нужны для
проверки callback. Не очищайте storage между вызовом login() и возвратом браузера
на redirectUri.
Перенаправление после входа
Если после успешного входа нужно открыть определённую страницу приложения,
передайте redirectAfterLoginTo:
await auth.login({
redirectAfterLoginTo: '/dashboard',
});
Можно передавать query-параметры и hash:
await auth.login({
redirectAfterLoginTo: '/dashboard?tab=profile#settings',
});
Используйте относительные адреса вашего приложения. Внешние URL не поддерживаются.
Не путайте
redirectAfterLoginToсredirectUri.
redirectUri— OIDC callback URL, который регистрируется в Авторизе.
redirectAfterLoginTo— страница вашего приложения, на которую пользователь попадёт после завершения авторизации.
Если параметр не передан, SDK завершит авторизацию без дополнительного перенаправления на указанную страницу.
Проверка состояния авторизации
Текущее состояние можно получить через getAuthState():
const state = auth.getAuthState();
console.log(state);
// {
// isAuthenticated: boolean,
// isLoading: boolean,
// user: User | null
// }
Также доступны свойства:
auth.isAuthenticated; auth.isLoading; auth.user;
Например:
if (auth.isAuthenticated) {
console.log('Пользователь авторизован');
}
isLoading
isLoading имеет значение true, пока SDK восстанавливает сессию после
создания экземпляра.
Например:
if (auth.isLoading) {
// показать состояние загрузки
}
if (auth.isAuthenticated) {
// пользователь авторизован
}
Восстановление сессии
При создании экземпляра SDK автоматически проверяет сохранённую сессию.
Поэтому после перезагрузки страницы не нужно повторно выполнять login().
Если сохранённая сессия действительна, пользователь остаётся авторизованным.
Получение пользователя
Используйте getUser():
const user = await auth.getUser();
Если пользователь авторизован, метод возвращает:
{
id: string;
email?: string;
name?: string;
}
Если активной сессии нет, возвращается:
null
Текущего пользователя также можно получить через:
auth.user;
Идентификатор пользователя соответствует идентификатору профиля пользователя в проекте Авторизы.
Получение Access Token
Для запросов к API используйте:
const token = await auth.getAccessToken();
SDK автоматически проверяет срок действия Access Token. Если до истечения осталось меньше запаса безопасности, SDK запускает refresh заранее, чтобы токен не истёк между проверкой и API-запросом.
Если access token истёк, SDK пытается получить новый с помощью refresh token.
Это позволяет приложению не заниматься обновлением токенов самостоятельно.
Например:
const token = await auth.getAccessToken();
const response = await fetch('/api/data', {
headers: {
Authorization: `Bearer ${token}`,
},
});
Если пользователь не авторизован, метод выбросит AuthorizaError с кодом:
USER_NOT_AUTHENTICATED
Если refresh token больше недействителен или истёк, текущая сессия считается недействительной, SDK очищает её, а приложение должно инициировать повторную авторизацию.
Выход
Для завершения локальной сессии используйте:
await auth.logout();
Метод удаляет сохранённую локальную сессию, очищает данные незавершённого flow и сообщает об изменении состояния другим вкладкам.
SDK не перенаправляет пользователя на страницу выхода Авторизы.
Это локальный logout. Если приложению нужен отдельный provider logout или завершение
центральной сессии, проверьте наличие такого сценария в OIDC-контракте отдельно; не
приписывайте его методу auth.logout().
Отслеживание изменений авторизации
Чтобы реагировать на вход, выход или восстановление сессии, можно подписаться на изменения состояния:
const unsubscribe = auth.onAuthStateChanged((state) => {
console.log(state.isAuthenticated);
console.log(state.user);
});
Когда подписка больше не нужна, вызовите функцию отписки:
unsubscribe();
Также доступен альтернативный API:
const unsubscribe = auth.on('authStateChanged', (state) => {
// ...
});
SDK также синхронизирует состояние авторизации между вкладками браузера.
Обработка callback
Отдельно обрабатывать OIDC callback не требуется.
Создайте экземпляр SDK на странице, указанной в redirectUri:
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
});
SDK автоматически определит, что текущий URL является callback URL, и обработает authorization code.
Отдельный вызов handleCallback() не нужен.
SDK можно создавать на любой странице приложения. Если текущий URL является callback URL, обработка authorization code выполняется автоматически.
Во время обработки callback SDK:
- получает authorization code;
- проверяет
state; - выполняет обмен authorization code на токены;
- проверяет ID Token;
- создаёт сессию пользователя.
Обработка ошибок
Ошибки SDK представлены классом AuthorizaError.
Для методов, возвращающих Promise, ошибки можно обрабатывать через try / catch:
try {
const token = await auth.getAccessToken();
} catch (error) {
console.error(error);
}
Для проверки ошибки используйте isAuthorizaError():
import {
createAuthoriza,
isAuthorizaError,
} from '@authoriza/sdk';
try {
const token = await auth.getAccessToken();
} catch (error) {
if (isAuthorizaError(error)) {
console.error(error.code);
}
}
Для асинхронных ошибок authentication flow можно использовать onError:
const auth = createAuthoriza({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://example.com/auth/callback',
onError(error) {
console.error(error.code, error.message);
},
});
Коды ошибок
| Код | Описание |
|---|---|
INVALID_CONFIG | Некорректная конфигурация SDK |
DISCOVERY_FAILED | Ошибка OIDC Discovery |
NETWORK_ERROR | Ошибка сетевого запроса |
AUTH_FLOW_IN_PROGRESS | Другой authentication flow уже выполняется |
INVALID_STATE | Некорректный OAuth state |
AUTHORIZATION_ERROR | Сервер авторизации вернул ошибку |
TOKEN_EXCHANGE_FAILED | Не удалось обменять authorization code на токены |
TOKEN_REFRESH_FAILED | Не удалось обновить access token |
USER_NOT_AUTHENTICATED | Пользователь не авторизован |
INVALID_SESSION | Сессия недействительна |
STORAGE_ERROR | Ошибка хранилища сессии |
USER_CANCELLED | Пользователь отменил авторизацию |
INVALID_REDIRECT_AFTER_LOGIN | Некорректный redirectAfterLoginTo |
INVALID_NONCE | Некорректный nonce ID Token |
UNSUPPORTED_TOKEN_TYPE | Неподдерживаемый тип токена |
Используйте error.code, а не error.message: код является стабильной частью
публичного API, а текст сообщения может измениться. Для пользовательского интерфейса
показывайте собственное понятное сообщение, а технические детали оставляйте в
диагностическом журнале без токенов и секретов.
Работа с токенами
SDK получает токены в процессе стандартного OIDC Authorization Code Flow.
После успешного входа приложение может использовать:
const token = await auth.getAccessToken();
SDK автоматически обновляет access token после его истечения, если в сессии доступен refresh token.
Для обновления используется стандартный OAuth token endpoint Авторизы.
Приложению не нужно самостоятельно формировать refresh-запросы.
SDK также учитывает возможность изменения refresh token при обновлении сессии: если сервер выдаёт новый refresh token, SDK использует его для дальнейших обновлений.
SSR и фреймворки
SDK не привязан к конкретному фреймворку и может использоваться с:
- React
- Vue
- Angular
- Svelte
- Next.js
- Nuxt
- другими JavaScript / TypeScript веб-приложениями
SDK поддерживает SSR-safe импорт и создание экземпляра: импорт библиотеки и
вызов createAuthoriza() не требуют наличия browser globals.
При этом непосредственно authentication flow выполняется в браузере.
SSR-safe означает, что импорт SDK и вызов createAuthoriza() не требуют
window в момент создания. Это не означает, что browser flow можно выполнить на
сервере. Инициализацию, которая должна читать callback URL или менять window.location,
выполняйте в браузерном контексте приложения.
Что SDK делает за вас
SDK берет на себя основные технические детали OAuth 2.0 / OpenID Connect:
- Authorization Code Flow с PKCE;
- OIDC Discovery;
- обработку authorization callback;
- создание и проверку
state; - создание и проверку
nonce; - работу с PKCE;
- обмен authorization code на токены;
- проверку ID Token;
- хранение сессии;
- восстановление сессии после перезагрузки;
- автоматическое обновление access token;
- защиту от параллельных refresh-запросов;
- синхронизацию состояния между вкладками;
- обработку ошибок authentication flow.
Это позволяет приложению работать с простой моделью:
login()
↓
пользователь авторизуется
↓
auth.isAuthenticated
↓
auth.user
↓
auth.getAccessToken()
Вам не нужно самостоятельно реализовывать эти части OIDC-протокола.
Пример готового приложения
Полный пример React SPA с использованием SDK:
Если вы хотите посмотреть, как выглядит такая же интеграция без SDK, используйте отдельный пример:
Он показывает прямую интеграцию с Авторизой через OIDC без использования SDK.
API и исходный код
Исходный код SDK и полный список API доступны на GitHub:
SDK распространяется под лицензией MIT.