Виджет входа
Подключите sdk.js и вызовите login — откроется окно входа, а в onSuccess вернётся код
авторизации. Ниже — вызов на каждом стеке, параметры, конфигурация окна и коды ошибок.
Сквозной пример «с нуля до токена» — быстрый старт.
Метод login
Заголовок раздела «Метод login»Каждая вкладка самодостаточна — подключение и вызов.
<script src="https://id.fidmos.com/js/sdk.js" data-client-id="ВАШ_CLIENT_ID"></script><script>
window.FidmosID.login({
clientId: 'ВАШ_CLIENT_ID',
redirectUri: 'https://partner.example/callback',
scope: 'openid profile email',
onSuccess: async ({ code, state, codeVerifier }) => {
// обменяйте code на токен на своём бэкенде: POST /login/callback
await fetch('/login/callback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code, state, codeVerifier }),
});
location.assign('/logged-in');
},
onCancel: () => {
// человек закрыл окно — это не ошибка
},
onError: ({ code }) => {
// code: 'invalid_arguments' | 'already_open' | 'unavailable'
},
});
</script>npm install fidmos-idimport { useState } from 'react';
import { login } from 'fidmos-id';
export function LoginButton() {
const [busy, setBusy] = useState(false);
const signIn = () => {
setBusy(true);
login({
clientId: 'ВАШ_CLIENT_ID',
redirectUri: 'https://partner.example/callback',
scope: 'openid profile email',
onSuccess: async ({ code, state, codeVerifier }) => {
// обменяйте code на токен на своём бэкенде: POST /login/callback
await fetch('/login/callback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code, state, codeVerifier }),
});
location.assign('/logged-in');
},
onCancel: () => setBusy(false),
onError: () => setBusy(false),
});
};
return (
<button type="button" onClick={signIn} disabled={busy}>
Войти через Fidmos
</button>
);
}npm install fidmos-id<script setup>
import { ref } from 'vue';
import { login } from 'fidmos-id';
const busy = ref(false);
function signIn() {
busy.value = true;
login({
clientId: 'ВАШ_CLIENT_ID',
redirectUri: 'https://partner.example/callback',
scope: 'openid profile email',
onSuccess: async ({ code, state, codeVerifier }) => {
// обменяйте code на токен на своём бэкенде: POST /login/callback
await fetch('/login/callback', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code, state, codeVerifier }),
});
location.assign('/logged-in');
},
onCancel: () => (busy.value = false),
onError: () => (busy.value = false),
});
}
</script>
<template>
<button type="button" :disabled="busy" @click="signIn">Войти через Fidmos</button>
</template>| Параметр | Назначение |
|---|---|
clientId |
идентификатор вашего клиента |
redirectUri |
адрес возврата вашего приложения — тот же, что зарегистрирован в кабинете |
scope |
запрашиваемые данные, напр. 'openid profile email'; для id_token нужен openid |
state |
необязательный; ваша строка — вернётся в onSuccess без изменений |
nonce |
необязательный; попадёт в id_token — тогда сверьте его на бэкенде (expectedNonce), иначе штатная проверка отвергнет токен |
config |
вид окна: способы, кошельки, язык, тексты — Конфигурация окна |
onSuccess({ code, state, codeVerifier }) |
вход удался — код авторизации и PKCE-code_verifier |
onCancel() |
человек закрыл окно |
onError({ code }) |
окно не открылось |
code одноразовый и сам по себе токена не даёт: обменяйте его на своём бэкенде на
/oauth/token, передав codeVerifier из onSuccess и свой client_secret — как в
быстром старте.
Конфигурация окна
Заголовок раздела «Конфигурация окна»Необязательный объект config меняет вид окна — способы входа, список кошельков, язык и
тексты. Он клиентский: живёт в вашем вызове login({ config }) и ничего не меняет на
сервере (границу — origin, redirect_uri, скоупы — держит сервер). Собрать наглядно и
скопировать готовый код — в конфигураторе.
| Опция | Тип | По умолчанию | Что задаёт |
|---|---|---|---|
methods |
('email' | 'telegram' | 'wallet')[] |
все три | какие способы входа показать |
wallets |
string[] (rdns) |
весь каталог | состав кошельков (см. ниже) |
locale |
'ru' | 'en' |
'ru' |
язык интерфейса окна |
theme |
'light' | 'dark' | 'auto' |
'dark' |
тема окна; auto — по системной prefers-color-scheme |
title |
string |
«Вход» | заголовок окна |
terms.tos |
string (URL) |
— | ссылка на ваши «Условия» |
terms.privacy |
string (URL) |
— | ссылка на вашу «Политику» |
Объект config одинаков на любом стеке — он идёт вторым полем в login({ …, config })
(форма вызова на каждом стеке — в методе login):
config: {
methods: ['email', 'wallet'],
wallets: ['io.metamask', 'io.rabby', 'app.phantom'],
locale: 'en',
theme: 'light',
title: 'Войти в Acme',
terms: {
tos: 'https://partner.example/tos',
privacy: 'https://partner.example/privacy',
},
}
Ссылки условий берутся, только если это полный http(s)-URL; иначе строка отбрасывается.
wallets — состав, а не порядок
Заголовок раздела «wallets — состав, а не порядок»wallets — allow-list по rdns: он задаёт, какие кошельки показать. Порядок в окне
всегда каталожный (по популярности), а установленные у пользователя поднимаются наверх —
wallets порядок не задаёт. Пустой или отсутствующий wallets — весь каталог.
| Кошелёк | rdns |
|---|---|
| MetaMask | io.metamask |
| Rabby | io.rabby |
| Trust Wallet | com.trustwallet.app |
| Coinbase Wallet | com.coinbase.wallet |
| Phantom | app.phantom |
| OKX Wallet | com.okex.wallet |
| Rainbow | me.rainbow |
| Zerion | io.zerion.wallet |
| Brave Wallet | com.brave.wallet |
Строку установки для необнаруженного кошелька дают только эти rdns; кошелёк с другим rdns
покажется, лишь если он обнаружен в браузере.
Исходы onError
Заголовок раздела «Исходы onError»| Код | Что произошло |
|---|---|
invalid_arguments |
не передан clientId или redirectUri |
already_open |
окно уже открыто |
unavailable |
окно не загрузилось (сеть, таймаут, закрыто до готовности) |
Отмена (onCancel) ошибкой не считается — не показывайте по ней сообщение об ошибке.
Разбор всех кодов ошибок — в справочнике.