Captcha Войти

Подключение капчи к сайту

Три шага: получить ключи, вставить виджет в форму, проверить токен на сервере.

1. Ключи

Подключите сайт в кабинете — укажите домены, на которых будет работать виджет. Вы получите sitekey (публичный, для страницы) и secret (только для сервера; показывается один раз).

Режимы проверки

РежимЧто видит посетительЧто делает сайт
СтандартныйГалочку (или ничего — в невидимом режиме); задание — только при подозрении: символы, слайдер, выбор картинок или поворотПропускает при success: true
Только оценка
как reCAPTCHA v3
Никаких заданийСам решает по score: например, ≥ 0.5 — SMS, модерация или отказ
Только proof-of-workГалочка ставится сама за секунду, без кликовПропускает при success: true; телеметрия не собирается — подходит, когда важна приватность, но защищает только от массовых ботов

Режим и набор заданий — в настройках сайта в кабинете или через API кабинета.

2. Виджет

Галочка «Я не робот» в форме:

<script src="https://captcha.mpdevelop.ru/widget.js" async defer></script>

<form method="post" action="/register">
  <input name="email">
  <div class="captcha-widget"
       data-sitekey="ck_…"
       data-action="registration"
       data-callback="onCaptcha"></div>
  <button>Зарегистрироваться</button>
</form>
АтрибутНазначение
data-sitekeyПубличный ключ сайта (обязателен)
data-actionДействие: login, registration… Попадает в токен, сервер может требовать совпадения. Латиница, цифры, _, /
data-callbackИмя глобальной функции, вызывается с токеном
data-expired-callbackТокен истёк (через 3 минуты) — галочка снята, нужно пройти снова
data-error-callbackОшибка проверки, аргумент — код ошибки
data-themelight или dark
data-langru или en; по умолчанию — язык страницы (<html lang>), затем браузера
data-input-nameИмя скрытого поля токена, по умолчанию captcha-token

Невидимый режим — без галочки, проверка при отправке формы:

form.addEventListener('submit', async (event) => {
  event.preventDefault();
  const token = await CaptchaWidget.execute({ sitekey: 'ck_…', action: 'login' });
  form.elements['captcha-token'].value = token;
  form.submit();
});

Задание поверх страницы появится только при высоком риске. Без клика у сервиса меньше сигналов, поэтому невидимый режим чаще показывает задание на уровнях защиты «Высокий» и выше.

API: CaptchaWidget.render(el, options) → id, execute(id | {sitekey, action}) → Promise<token>, reset(id), getResponse(id).

3. Проверка на сервере

POST https://captcha.mpdevelop.ru/api/v1/verify, тело form-urlencoded или JSON:

ПолеНазначение
secretСекретный ключ (или заголовок Authorization: Bearer …)
tokenЗначение поля captcha-token из формы
actionНеобязательно: ожидаемое действие; при несовпадении — action-mismatch
ipНеобязательно: IP посетителя; в ответе будет ip_match
{"success": true, "score": 0.1, "action": "registration", "hostname": "example.com",
 "challenge": false, "challenge_type": null, "challenge_ts": "2026-10-06T12:00:00+00:00", "ip_match": true}

{"success": false, "error": "invalid-or-used-token"}

Ошибки: missing-input, invalid-secret, invalid-token, invalid-or-used-token (истёк или уже проверен), token-site-mismatch, action-mismatch, rate-limited.

Пример на PHP без зависимостей:

$response = file_get_contents('https://captcha.mpdevelop.ru/api/v1/verify', false, stream_context_create(['http' => [
    'method' => 'POST',
    'header' => 'Content-Type: application/x-www-form-urlencoded',
    'content' => http_build_query([
        'secret' => getenv('CAPTCHA_SECRET'),
        'token' => $_POST['captcha-token'] ?? '',
        'action' => 'registration',
        'ip' => $_SERVER['REMOTE_ADDR'],
    ]),
    'timeout' => 3,
]]));
$ok = ($response !== false) && (json_decode($response, true)['success'] ?? false) === true;

Токен одноразовый и живёт 3 минуты. Проверяйте его до выполнения действия, а не после. Готовый клиент — пакет sdk/php в репозитории сервиса.

mode — standard, score или pow (в режиме pow score = null). challenge_type — image (символы), slider (пазл), grid (картинки), rotate (поворот), audio (аудио-задание для незрячих) или null (прошёл без задания). Аудио проще для ботов с распознаванием речи — для особо чувствительных действий это можно учесть.

Готовые интеграции

  • Symfony — бандл: $builder->add('captcha', CaptchaType::class, ['action' => 'login']), атрибут #[CaptchaValid], {{ captcha_widget('login') }}.
  • Laravel — @captcha('login') в Blade и правило 'captcha-token' => 'required|captcha:login'.
  • 1С-Битрикс — модуль captcha.client: регистрация, вход и веб-формы без правки кода.

Пакет startup/captcha-client (sdk/php) и модуль sdk/bitrix в репозитории сервиса — там же инструкции.

API кабинета

Сайтами и ключами можно управлять из скриптов и CI. Токен — в кабинете, раздел «API»; передаётся заголовком Authorization: Bearer cpt_….

ЗапросЧто делает
GET /api/v1/sitesСписок своих сайтов
POST /api/v1/sitesПодключить сайт; ответ содержит secret — единственный раз
GET · PATCH · DELETE /api/v1/sites/{id}Посмотреть, изменить настройки, удалить
POST /api/v1/sites/{id}/secretВыпустить новый секрет (старый перестаёт работать сразу)
GET /api/v1/sites/{id}/stats?days=30&period=7dДневная статистика и аналитика
curl -X PATCH https://captcha.mpdevelop.ru/api/v1/sites/7 \
  -H "Authorization: Bearer $CAPTCHA_API_TOKEN" -H "Content-Type: application/json" \
  -d '{"security_level": "high", "action_limits": {"login": {"limit": 10, "window": 600}}}'

Поля сайта: name, hosts, security_level, action_levels, action_limits, enabled, verification_mode, challenge_types. Ошибки проверки — 422 с разбором по полям.

Определение провайдера по IP: IP to ASN by DB-IP (CC BY 4.0).