Пример бэкенда (Node.js)
Полный рабочий бэкенд для встроенного окна: он обменивает пришедший из браузера код на токен
и проверяет id_token. Разбор по шагам — в быстром старте; здесь —
один готовый модуль, который можно скопировать и запустить.
Что где выполняется
Заголовок раздела «Что где выполняется»- В браузере:
window.FidmosID.login(...)из виджета. Окно само заводит поток и вonSuccessотдаёт{ code, state, codeVerifier }, а страница передаёт их на этот бэкенд. - На бэкенде (этот код): обмен кода на токен и проверка
id_token. Здесь живётclient_secret;code_verifierбэкенд получает из браузера и шлёт на/oauth/token.
Установка
Заголовок раздела «Установка»npm install openid-client express
Нужен Node.js 20+ (модуль использует встроенный fetch и ESM).
Настройка
Заголовок раздела «Настройка»// config.js
export const ISSUER = 'https://id.fidmos.com';
export const CLIENT_ID = process.env.FIDMOS_CLIENT_ID;
export const CLIENT_SECRET = process.env.FIDMOS_CLIENT_SECRET; // только на бэкенде!
export const REDIRECT_URI = 'https://partner.example/callback'; // тот же, что зарегистрирован
Модуль входа
Заголовок раздела «Модуль входа»// fidmos-id.js
import * as client from 'openid-client';
import { ISSUER, CLIENT_ID, CLIENT_SECRET, REDIRECT_URI } from './config.js';
// Discovery делаем один раз при старте: адреса эндпоинтов и ключи проверки берутся
// из /.well-known/openid-configuration, а не хардкодятся.
const config = await client.discovery(new URL(ISSUER), CLIENT_ID, CLIENT_SECRET);
// Завершить вход: обменять код на токен и проверить id_token.
// code и codeVerifier пришли из onSuccess виджета через вашу страницу.
export async function finishLogin({ code, codeVerifier }) {
// В callback-URL кладём только код — из него openid-client берёт параметры ответа.
const callbackUrl = new URL(REDIRECT_URI);
callbackUrl.searchParams.set('code', code);
// Обмен кода на токен + проверка id_token: подпись по JWKS из discovery,
// iss = issuer, aud = наш client_id, срок exp. PKCE подтверждаем verifier'ом из браузера.
const tokens = await client.authorizationCodeGrant(config, callbackUrl, {
pkceCodeVerifier: codeVerifier,
idTokenExpected: true,
});
// sub — парный идентификатор пользователя: стабильный для вашего клиента.
const { sub, email, email_verified: emailVerified } = tokens.claims();
return { sub, email, emailVerified, accessToken: tokens.access_token };
}
Подключение (Express)
Заголовок раздела «Подключение (Express)»// server.js
import express from 'express';
import { finishLogin } from './fidmos-id.js';
const app = express();
app.use(express.json());
// onSuccess виджета прислал { code, state, codeVerifier }; страница передаёт их сюда.
app.post('/login/callback', async (req, res) => {
try {
const { sub } = await finishLogin(req.body);
// Опознайте пользователя по sub и заведите свою сессию (express-session, JWT-cookie и т.п.).
res.json({ ok: true, sub });
} catch (err) {
res.status(400).json({ ok: false });
}
});
app.listen(3000);
Что дальше
Заголовок раздела «Что дальше»- Забрать имя и аватар — профиль пользователя (те же claims есть и в
id_token, который уже проверен выше). - Контракт виджета целиком — виджет входа.
- Классический OAuth2 без виджета — редиректный вход.