Настройка серверной части для интеграции мобильной авторизации через виджет или SDK
Для работы вам нужно реализовать два эндпоинта на своём сервере:
| Эндпоинт | Кто вызывает | Назначение |
|---|---|---|
POST /api/token |
Виджет/SDK (браузер) | Выдать init-токен для старта верификации |
POST /api/siteverify |
Ваш фронтенд после получения события verified (браузер) | Подтвердить результат верификации через MobileID API (server-to-server) |
Имена эндпоинтов можно выбрать произвольно.
Пример эндпоинта для виджета
const widget = new MobileIDWidget({
tokenUrl: '/api/token', /* URL вашего бэкенда для получения токена */
});Пример эндпоинта для SDK
const mid = new MobileID({
tokenUrl: '/api/token', /* URL вашего бэкенда для получения токена */
});Учётные данные
Получите в личном кабинете в разделе мобильная авторизация:
| Параметр | Описание |
|---|---|
CLIENT_ID |
Публичный идентификатор виджета |
API_SECRET |
Секретный ключ для подписи запросов — никогда не передаётся на фронтенд |
Эндпоинт 1 — получение init-токена
Виджет/SDK вызывает этот эндпоинт автоматически при каждом старте верификации. Ваш сервер подписывает запрос и проксирует его в MobileID API.
Что присылает виджет/SDK
POST /api/token
Content-Type: application/json
{ "fingerprint_hash": "a3f9c..." }Если в виджете настроена капча, её токен приходит как query-параметр:
POST /api/token?captcha_token=<токен_капчи>Что нужно сделать на сервере
- (Опционально) Проверить токен капчи через API провайдера капчи
- Сформировать подпись
- Отправить подписанный запрос в MobileID API
- Вернуть ответ виджету
Алгоритм подписи
timestamp = текущее время в секундах (Unix), как строка
message = CLIENT_ID + fingerprint_hash + timestamp
signature = HMAC-SHA256(message, API_SECRET)Запрос к MobileID API
POST https://midsdk.smsaero.ru/api/token
Content-Type: application/json
{
"client_id": "pub_abc123",
"fingerprint_hash": "a3f9c...",
"timestamp": "1715000000",
"signature": "e3b0c4..."
}Ответ виджету/SDK
Верните ответ MobileID API без изменений:
{
"token": "<init-token>"
}Эндпоинт 2 — проверка результата (server-to-server)
После успешной верификации вызывается колбек:
// Вариант для виджета
onVerified: (data) => {
// data.verify_token — токен результата
// data.session_id — идентификатор сессии
// data.phone — номер телефона
}
// Вариант для SDK
verified: (data) => {
// data.verify_token — токен результата
// mid.getSessionId() — идентификатор сессии
// mid.getPhone() — номер телефона
}Доверять этим данным напрямую нельзя — они пришли из браузера. Чтобы убедиться, что верификация действительно прошла, отправьте verify_token и session_id на ваш сервер, а сервер проверит их в MobileID API. Это и есть server-to-server проверка.
Принцип проверки
Браузер Ваш сервер MobileID API
│ │ │
│ onVerified / verified │ │
│ ──────────────────────► │ │
│ │ POST /api/siteverify │
│ │ {session_id, │
│ │ verify_token, ...} │
│ │ ─────────────────────► │
│ │ { success: true, │
│ │ phone: "7..." } │
│ │ ◄───────────────────── │
│ { ok: true } │ │
│ ◄────────────────────── │ │Только после успешного ответа MobileID API считайте номер подтверждённым и выполняйте бизнес-логику (вход, привязка номера и т.д.).
Что отправляет ваш фронтенд
POST /api/siteverify
Content-Type: application/json
{
"session_id": "<из onVerified>",
"verify_token": "<из onVerified>"
}Что нужно сделать на сервере
- Принять
session_idиverify_token - Сформировать подпись
- Отправить запрос в MobileID API
- Вернуть результат фронтенду
Алгоритм подписи
timestamp = текущее время в секундах (Unix), как строка
message = CLIENT_ID + session_id + timestamp
signature = HMAC-SHA256(message, API_SECRET)Запрос к MobileID API
POST https://midsdk.smsaero.ru/api/siteverify
Content-Type: application/json
{
"client_id": "pub_abc123",
"session_id": "<session_id>",
"verify_token": "<verify_token>",
"timestamp": "1715000000",
"signature": "e3b0c4..."
}Ответ MobileID API
{
"success": true,
"phone": "79161234567",
"status": "verified" // любой статус отличный от verified считается как неудачная верификация
}Пример реализации на PHP
Требования: PHP 5.4+, расширения curl и hash (входят в стандартную поставку).
Класс MobileIDBackend
Скопируйте класс в свой проект:
<?php
class MobileIDBackend
{
private $clientId;
private $apiSecret;
private $sdkBackendUrl;
private $timeout;
/**
* @param array $config {
* @type string $clientId Публичный идентификатор клиента (обязательный)
* @type string $apiSecret Секретный ключ для подписи запросов (обязательный)
* @type string $sdkBackendUrl Базовый URL MobileID API без слеша на конце
* (обязательный, используйте https://midsdk.smsaero.ru)
* @type int $timeout Таймаут cURL в секундах (по умолчанию 10)
* }
*/
public function __construct(array $config)
{
$this->clientId = $config['clientId'];
$this->apiSecret = $config['apiSecret'];
$this->sdkBackendUrl = rtrim($config['sdkBackendUrl'], '/');
$this->timeout = isset($config['timeout']) ? (int)$config['timeout'] : 10;
}
/**
* Получить init-токен для виджета.
* Вызывается из эндпоинта /api/token.
*
* @param string $fingerprintHash Хэш из тела запроса виджета
* @return array Массив из двух элементов: [HTTP-статус, тело ответа]
*/
public function getToken($fingerprintHash)
{
if ($fingerprintHash === '') {
return [400, ['error' => 'missing fingerprint_hash']];
}
$timestamp = (string)time();
$signature = hash_hmac(
'sha256',
$this->clientId . $fingerprintHash . $timestamp,
$this->apiSecret
);
return $this->request('/api/token', [
'client_id' => $this->clientId,
'fingerprint_hash' => $fingerprintHash,
'timestamp' => $timestamp,
'signature' => $signature,
]);
}
/**
* Проверить результат верификации (server-to-server).
* Вызывается из эндпоинта /api/siteverify.
*
* @param string $sessionId ID сессии из события onVerified
* @param string $verifyToken Токен результата из события onVerified
* @return array Массив из двух элементов: [HTTP-статус, тело ответа]
*/
public function siteVerify($sessionId, $verifyToken)
{
if ($sessionId === '' || $verifyToken === '') {
return [400, ['error' => 'missing session_id or verify_token']];
}
$timestamp = (string)time();
$signature = hash_hmac(
'sha256',
$this->clientId . $sessionId . $timestamp,
$this->apiSecret
);
return $this->request('/api/siteverify', [
'client_id' => $this->clientId,
'session_id' => $sessionId,
'verify_token' => $verifyToken,
'timestamp' => $timestamp,
'signature' => $signature,
]);
}
/**
* @param string $path Путь, например '/api/token'
* @param array $payload Данные для отправки
* @return array [HTTP-статус, декодированное тело]
*/
private function request($path, array $payload)
{
$url = $this->sdkBackendUrl . $path;
$json = json_encode($payload);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $json,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
]);
$raw = curl_exec($ch);
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlErr = curl_errno($ch) ? curl_error($ch) : null;
curl_close($ch);
if ($curlErr !== null) {
return [502, ['error' => 'sdk backend unavailable', 'details' => $curlErr]];
}
$body = json_decode($raw, true);
if ($body === null) {
return [502, ['error' => 'invalid response from sdk backend']];
}
return [$httpCode, $body];
}
}Использование — эндпоинт /api/token
<?php
require_once 'MobileIDBackend.php';
header('Content-Type: application/json');
$backend = new MobileIDBackend([
'clientId' => 'your_client_id',
'apiSecret' => 'your_api_secret',
'sdkBackendUrl' => 'https://midsdk.smsaero.ru',
]);
$input = json_decode(file_get_contents('php://input'), true);
$input = $input ? $input : [];
// Проверка капчи (если в виджете задан getCaptchaToken)
// $captchaToken = isset($_GET['captcha_token']) ? $_GET['captcha_token'] : '';
// ... верификация токена через API провайдера капчи ...
$fingerprintHash = isset($input['fingerprint_hash']) ? $input['fingerprint_hash'] : '';
list($status, $body) = $backend->getToken($fingerprintHash);
http_response_code($status);
echo json_encode($body);Использование — эндпоинт /api/siteverify
<?php
require_once 'MobileIDBackend.php';
header('Content-Type: application/json');
$backend = new MobileIDBackend([
'clientId' => 'your_client_id',
'apiSecret' => 'your_api_secret',
'sdkBackendUrl' => 'https://midsdk.smsaero.ru',
]);
$input = json_decode(file_get_contents('php://input'), true);
$input = $input ? $input : [];
$sessionId = isset($input['session_id']) ? $input['session_id'] : '';
$verifyToken = isset($input['verify_token']) ? $input['verify_token'] : '';
list($status, $body) = $backend->siteVerify($sessionId, $verifyToken);
if ($status === 200 && !empty($body['success'])) {
// Верификация подтверждена — выполняем бизнес-логику
$phone = $body['phone']; // номер в формате 79161234567
}
http_response_code($status);
echo json_encode($body);Настройка виджета/SDK на фронтенд
После реализации эндпоинтов передайте адрес первого в опцию tokenUrl:
// Вариант для виджета
const widget = new MobileIDWidget({
tokenUrl: 'https://your-site.ru/api/token', // ваш эндпоинт
onVerified: async (data) => {
// Отправляем на свой сервер для server-to-server проверки
const res = await fetch('/api/siteverify', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
session_id: data.session_id,
verify_token: data.verify_token,
}),
});
const result = await res.json();
if (result.success) {
// Номер подтверждён
}
},
});
// Вариант для SDK
const mid = new MobileID({
tokenUrl: 'https://your-site.ru/api/token', // ваш эндпоинт
});
mid.on('verified', async (data) => {
const res = await fetch('/api/siteverify', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
session_id: mid.getSessionId(),
verify_token: data.verify_token,
}),
});
const result = await res.json();
if (result.success) {
// Номер подтверждён
}
});Подробную информацию по виджету или SDK можно посмотреть в разделе мобильная авторизация
Безопасность
API_SECRETдолжен храниться только на сервере — не передавайте его в браузер и не включайте в фронтенд-сборки- server-to-server проверка через
/api/siteverifyобязательна —verify_tokenбез неё не является доказательством верификации verify_tokenдействителен только для одной проверки — после успешного ответа MobileID API он становится недействительным
Вы соглашаетесь с условиями обработки, используя сайт. Подробнее