Флида

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().
autoAuthorizationPromise<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_stateState отсутствует, транзакция истекла, уже потреблена либо не совпадает с ответом.
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_closedPopup закрыт до получения результата.
timeoutPopup не вернул результат в течение 10 минут.
invalid_responseНекорректный JSON или формат ответа API, FedCM, popup либо callback.
http_errorAPI вернул HTTP-ошибку без OAuth-кода. Статус доступен в error.status.
oauth_errorAPI, popup или callback вернул OAuth-ошибку. Код провайдера доступен в error.message; error.status заполнен только для HTTP-ответа.

Системные исключения не всегда представлены FlidaError. Сетевая ошибка fetch() может быть TypeError, ошибка хранилища или FedCM — браузерным исключением. При явной отмене SDK передает исходный signal.reason; обычный controller.abort() дает AbortError.

© 2026 ООО «Флида»