Web SDK
Подключение Флида ID к браузерному приложению через Web SDK.
Web SDK подключает Флида ID к сайту или браузерному приложению. Он управляет state и PKCE, запускает FedCM или OIDC, самостоятельно обменивает код на токены и получает данные пользователя.
Для входа по кнопке используйте authorize(). Режимы FedCM и OIDC задаются при создании экземпляра SDK. Результат автоматического входа и обработки redirect callback доступен через autoAuthorization.
SDK не принимает Client Secret и не передает scope. При обмене кода и обновлении токенов браузерный клиент передает client_id без секрета. Области доступа берутся из настроек проекта в консоли Флида ID.
Шаг 1. Подключите SDK
Обычный скрипт публикует FlidaSDK и FlidaError в глобальном объекте Flida:
<script src="https://id.flida.ru/sdk/v1/sdk.js"></script>Для браузерных ES-модулей используйте модульную сборку:
import { FlidaSDK, FlidaError } from 'https://id.flida.ru/sdk/v1/sdk.es.js'Шаг 2. Создайте экземпляр
const sdk = new Flida.FlidaSDK({
clientId: '019d9a8a-7f8b-7f54-9d4e-4a9ecc9fc609',
redirectUri: 'https://myapp.ru/callback',
fedcm: ['active', 'passive'],
mode: 'redirect',
})| Параметр | Описание |
|---|---|
clientId | Обязательный. Идентификатор проекта из консоли Флида ID. |
redirectUri | Обязательный. Абсолютный HTTP(S)-адрес без credentials и fragment. Он должен точно совпадать с Redirect URL в разделе Платформы | Web. Параметры OAuth-ответа в нем зарезервированы. |
fedcm | По умолчанию ['active', 'passive']. Передайте ['active'], ['passive'] или [], чтобы выбрать режимы или полностью отключить FedCM. |
mode | Режим OIDC: 'redirect' по умолчанию или 'popup'. Используется при отключенном active FedCM и при fallback из недоступного active FedCM. |
popupWidth | Запрашиваемая ширина OIDC popup в пикселях. По умолчанию и минимум — 700. |
popupHeight | Запрашиваемая высота OIDC popup в пикселях. По умолчанию и минимум — 700. |
Размеры popup должны быть конечными числами: дробные значения округляются до целых, значения меньше 700 поднимаются до 700. Некорректная конфигурация вызывает invalid_config при создании SDK. Браузер может ограничить фактические размеры окна; SDK не контролирует его последующее ручное изменение.
Настройки задаются в конструкторе. SDK сам генерирует криптографически случайные state и code_verifier и вычисляет code_challenge методом S256. Передавать собственные значения или менять режим через параметры authorize() не нужно и нельзя.
Зарегистрируйте адрес возврата
Зарегистрируйте redirectUri в консоли Флида ID в разделе Платформы | Web. Например, для redirectUri: 'https://myapp.ru/callback' укажите Redirect URL https://myapp.ru/callback.
Для FedCM origin страницы, с которой вызывается SDK, должен совпадать по схеме, хосту и порту с origin хотя бы одного зарегистрированного Web Redirect URL.
Для автоматической обработки redirect callback используйте тот же origin и вкладку: SDK должен прочитать сохраненную перед переходом транзакцию из sessionStorage. Для OIDC popup совпадение origin redirectUri и исходной страницы обязательно; SDK проверяет его до открытия окна.
Шаг 3. Запустите авторизацию
Вход по кнопке
Вызывайте authorize() прямо из обработчика действия пользователя, чтобы браузер разрешил active FedCM или popup:
async function signIn() {
try {
const tokens = await sdk.authorize()
if (tokens) {
const user = await sdk.getUser(tokens.access_token)
// Используйте токены и профиль в приложении.
console.log(user)
}
} catch (error) {
// Покажите ошибку входа в интерфейсе приложения.
console.error(error)
}
}
document.querySelector('#sign-in').addEventListener('click', signIn)FedCM и OIDC popup возвращают готовый TokenResponse. OIDC redirect запускает переход и возвращает undefined; токены получит экземпляр SDK на callback-странице через autoAuthorization.
| Настройки | Поведение authorize() |
|---|---|
В fedcm есть 'active' | Запускает active FedCM независимо от mode. Если необходимый FedCM API недоступен, продолжает через OIDC в режиме mode. |
В fedcm нет 'active', mode: 'redirect' | Запускает OIDC redirect. |
В fedcm нет 'active', mode: 'popup' | Запускает OIDC popup. |
Active FedCM использует mediation: 'required'. SDK передает провайдеру state, PKCE, redirect_uri и response_type=code. Значение credential.token является кодом авторизации, который SDK обменивает на токены.
Fallback выполняется только при fedcm_unavailable: когда браузер не поддерживает FedCM, active mode или custom params. Отмена пользователем, ошибки браузера, некорректный ответ и ошибка обмена кода передаются приложению без автоматического запуска OIDC.
Passive FedCM — автоматический вход
Если в fedcm есть 'passive', при создании SDK запускается одна фоновая попытка с mediation: 'optional'. Она ожидает выбора аккаунта без таймера и сама обменивает код на токены:
try {
const tokens = await sdk.autoAuthorization
if (tokens) {
const user = await sdk.getUser(tokens.access_token)
// Пользователь вошел без отдельного нажатия на кнопку.
console.log(user)
}
} catch (error) {
// Обработайте ошибку автоматического входа или обмена кода.
console.error(error)
}При недоступном FedCM, ответе браузера null или отмене фоновой попытки результат — undefined. Passive никогда не запускает OIDC fallback. При отключенном passive и отсутствии callback autoAuthorization также возвращает undefined.
authorize() сразу отменяет текущую passive-попытку, сохраняя пользовательскую активацию браузера. Поздний ответ отмененной попытки не обменивается на токены. При уходе со страницы попытка тоже отменяется. Ошибки остаются доступными через autoAuthorization, даже если приложение ожидает Promise позже.
OIDC redirect и callback
Для входа только через redirect отключите FedCM:
const sdk = new Flida.FlidaSDK({
clientId: '019d9a8a-7f8b-7f54-9d4e-4a9ecc9fc609',
redirectUri: 'https://myapp.ru/callback',
fedcm: [],
mode: 'redirect',
})
await sdk.authorize()На странице возврата создайте SDK с теми же clientId и redirectUri и ожидайте autoAuthorization. SDK сам распознает ответ, проверит транзакцию и обменяет код:
const callbackSDK = new Flida.FlidaSDK({
clientId: '019d9a8a-7f8b-7f54-9d4e-4a9ecc9fc609',
redirectUri: 'https://myapp.ru/callback',
fedcm: [],
mode: 'redirect',
})
try {
const tokens = await callbackSDK.autoAuthorization
if (tokens) {
const user = await callbackSDK.getUser(tokens.access_token)
// Сохраните результат входа в состоянии приложения.
console.log(user)
}
} catch (error) {
// Обработайте ошибку callback или обмена кода.
console.error(error)
}Ручной разбор code и state и отдельный обмен не требуются. Callback распознается по совпадению origin, пути и фиксированных query-параметров с redirectUri и наличию code, state или error. При сравнении адресов параметры OAuth-ответа исключаются. Они не должны входить в настроенный redirectUri: code, state, error, error_description, error_uri, iss, session_state.
Совпадение адреса без OAuth-ответа не запускает callback. Одна страница может быть точкой входа и возврата: при redirectUri: 'https://myapp.ru/' обычный заход на / использует конфигурацию входа, а /?code=...&state=... запускает обработку callback вместо passive FedCM.
До перехода SDK сохраняет code_verifier в sessionStorage. Транзакция привязана к clientId, redirectUri и state и действует 15 минут. Новый redirect заменяет предыдущую попытку для той же пары Client ID / redirect URI. Callback проверяет state и срок действия и удаляет транзакцию до сетевого запроса. OAuth-ошибка в callback также требует валидной транзакции.
Для автоматического обмена callback нужен доступ к исходной транзакции. На другом
origin она недоступна; при очистке или блокировке sessionStorage SDK вернет
invalid_state либо браузерную ошибку хранилища. Повторная обработка уже
потребленной транзакции завершается invalid_state.
Во время обработки callback authorize() возвращает authorization_in_progress и не отменяет обмен. После завершения callback, успешного или с ошибкой, authorize() начинает новый вход по конфигурации. autoAuthorization продолжает содержать результат первоначальной автоматической попытки или callback.
SDK не удаляет параметры callback из адресной строки. Приложение может очистить их через history.replaceState() после создания экземпляра, когда SDK уже прочитал ответ.
OIDC popup
Для входа через popup без FedCM задайте режим в конструкторе:
const sdk = new Flida.FlidaSDK({
clientId: '019d9a8a-7f8b-7f54-9d4e-4a9ecc9fc609',
redirectUri: 'https://myapp.ru/callback',
fedcm: [],
mode: 'popup',
popupWidth: 900,
popupHeight: 800,
})
async function signIn() {
const tokens = await sdk.authorize()
if (tokens) {
const user = await sdk.getUser(tokens.access_token)
console.log(user)
}
}
document.querySelector('#sign-in').addEventListener('click', signIn)Popup — отдельное окно браузера через window.open(). SDK открывает пустое окно до ожидания вычисления PKCE, затем загружает страницу Флида ID. В запросе используется response_mode=web_message.opener.
Флида ID отправляет результат через window.postMessage() на origin из redirectUri. SDK принимает сообщение только от созданного popup и origin Флида ID, проверяет действие oauth2_response_${state} и payload.state, закрывает окно и самостоятельно обменивает payload.code на токены. Ошибка в payload.error отклоняет вход. Для FedCM и popup verifier остается в памяти текущей попытки; sessionStorage не используется.
Шаг 4. Получите пользователя и обновите токены
const user = await sdk.getUser(tokens.access_token)
if (tokens.refresh_token) {
const renewedTokens = await sdk.refreshToken(tokens.refresh_token)
// Сохраните renewedTokens вместо предыдущего набора токенов.
const renewedUser = await sdk.getUser(renewedTokens.access_token)
console.log(renewedUser)
}SDK возвращает токены приложению и не сохраняет их в браузерное хранилище. Приложение управляет их хранением и обновлением.
Формат результатов
TokenResponse содержит обязательные строки access_token и token_type. Поля expires_in (число секунд), refresh_token и id_token необязательны в типах SDK. Проверяйте наличие refresh-токена перед обновлением. SDK обменивает и обновляет токены через POST /api/oidc/token с Content-Type: application/x-www-form-urlencoded.
getUser() вызывает GET /api/oidc/userinfo с Authorization: Bearer <access_token> и возвращает UserInfoResponse. Обязателен sub. Остальные поля зависят от данных пользователя и выданных областей доступа: given_name, family_name, middle_name, nickname, date_of_birth, sex, email, email_verified, phone_number, phone_number_verified. Не рассчитывайте на наличие необязательных полей. Подробности — в описании UserInfo.
Справочник API
| Метод или свойство | Результат |
|---|---|
authorize({ signal? }) | Promise<TokenResponse | undefined>. Новый вход по конфигурации; redirect возвращает undefined. Без параметров вызывается как authorize(). |
autoAuthorization | Promise<TokenResponse | undefined>. Результат первоначального passive FedCM или redirect callback. |
getUser(accessToken, signal?) | Promise<UserInfoResponse>. Актуальные данные пользователя. |
refreshToken(refreshToken, signal?) | Promise<TokenResponse>. Обновленный набор токенов. |
TypeScript-сборка экспортирует SDKConfig, AuthorizeOptions, AuthorizationMode, FedCMMode, TokenResponse, UserInfoResponse и ErrorCode, а также классы FlidaSDK и FlidaError.
Отмена и параллельные операции
Передайте signal в authorize() или вторым аргументом в getUser() и refreshToken():
const controller = new AbortController()
const authorization = sdk.authorize({ signal: controller.signal })
// В обработчике отмены в интерфейсе приложения.
controller.abort()
try {
await authorization
} catch (error) {
// При обычной отмене error.name равен 'AbortError'.
console.error(error)
}Авторизация блокируется до завершения входа и обмена кода. Второй одновременный authorize() возвращает authorization_in_progress; исключение — отмена текущей passive-попытки входом по кнопке. После запуска redirect метод завершен, поэтому задержанный или отмененный переход можно повторить. Отмена через signal действует до перехода; после навигации callback обрабатывает новый экземпляр SDK.
Ошибки SDK
Ошибки SDK представлены классом FlidaError. Машиночитаемый код доступен в error.code, HTTP-статус — в error.status, если он известен:
try {
const tokens = await sdk.authorize()
if (tokens) {
const user = await sdk.getUser(tokens.access_token)
console.log(user)
}
} catch (error) {
if (error instanceof Flida.FlidaError) {
console.error(error.code, error.status, error.message)
} else if (error instanceof DOMException && error.name === 'AbortError') {
// Операция отменена через AbortSignal.
} else {
// Ошибка браузера, хранилища или сети.
console.error(error)
}
}| Код | Когда возникает |
|---|---|
invalid_config | Некорректный Client ID, redirect URI, режим FedCM или OIDC, размеры popup либо несовпадение origin для OIDC popup. |
invalid_state | State отсутствует, транзакция истекла, уже потреблена либо не совпадает с ответом. |
transaction_exists | Внутренняя redirect-транзакция с таким state уже существует. SDK генерирует state самостоятельно. |
crypto_unavailable | Недоступен Web Crypto для случайных значений или PKCE S256. |
fedcm_unavailable | Внутренний сигнал недоступности FedCM, режима или custom params. Active запускает OIDC fallback в режиме mode; passive возвращает undefined. |
authorization_in_progress | Уже выполняется явный вход или обработка callback в этом экземпляре SDK. |
popup_blocked | Браузер заблокировал popup. |
popup_closed | Popup закрыт до получения результата. |
timeout | Popup не вернул результат в течение 10 минут. |
invalid_response | Некорректный JSON или формат ответа API, FedCM, popup либо callback. |
http_error | API вернул HTTP-ошибку без OAuth-кода. Статус доступен в error.status. |
oauth_error | API, popup или callback вернул OAuth-ошибку. Код провайдера доступен в error.message; error.status заполнен только для HTTP-ответа. |
Системные исключения не всегда представлены FlidaError. Сетевая ошибка fetch() может быть TypeError, ошибка хранилища или FedCM — браузерным исключением. При явной отмене SDK передает исходный signal.reason; обычный controller.abort() дает AbortError.