Введение

Captcha Hub — это адаптивная система защиты, разработанная для обеспечения безопасности веб-форм при минимальном вмешательстве в пользовательский опыт. Наша цель — эффективно блокировать ботов, оставаясь практически незаметными для реальных пользователей

Как это работает

Процесс проверки полностью автоматизирован и состоит из нескольких этапов:

  1. Инициализация виджета: На вашем сайте загружается наш легковесный JS-скрипт, который отрисовывает виджет "Я не робот"
  2. Пассивный анализ: В фоне скрипт собирает сотни анонимных поведенческих и технических сигналов (движение мыши, ритм нажатий, отпечаток браузера, репутация IP)
  3. Решение в реальном времени: Когда пользователь нажимает на чекбокс, собранные данные отправляются на наш сервер. Наша скоринговая модель мгновенно принимает решение
  4. Дополнительное задание (Challenge): Только если система не уверена в пользователе, ему будет показано простое дополнительное задание (например, ввести текст с картинки)
  5. Получение токена: После успешной проверки наш скрипт помещает одноразовый токен в скрытое поле вашей формы
  6. Серверная верификация: Ваш бэкенд отправляет этот токен и ваш `Secret Key` на наш сервер для финального подтверждения

Получение ключей

Для начала работы вам необходимо зарегистрироваться и создать конфигурацию капчи в панели управления. Вы получите два ключа:

  • Site Key (Публичный ключ): Используется в HTML-коде вашего сайта для отображения виджета. Его можно безопасно публиковать
  • Secret Key (Секретный ключ): Используется для безопасной сервер-серверной проверки. Никогда не раскрывайте этот ключ на клиентской стороне

Базовая установка (JS)

Интеграция на ваш сайт состоит из двух простых шагов

Шаг 1: Подключите скрипт

Вставьте этот код перед закрывающим тегом </body> на вашей странице

<script src="https://s3.cphub.ru/captcha.js" defer></script>
Скопировано

Шаг 2: Разместите виджет

Вставьте этот div в вашу форму. Замените ВАШ_SITE_KEY на ключ из панели управления.

<div class="cphb-captcha" style="height: 100px" data-sitekey="ВАШ_SITE_KEY"></div>
Скопировано

JavaScript API

Для продвинутого управления виджетом вы можете использовать глобальные JavaScript-функции. (В разработке)

Серверная проверка

Это самый важный шаг. После отправки формы вашим сервером, вы должны проверить полученный токен cphb-captcha-token, отправив POST-запрос на наш API

<?php

// Ваш приватный ключ, который вы храните в секрете
define('CPHUB_SECRET_KEY', 'ВАШ_SECRET_KEY');

/**
 * Функция для проверки токена Captcha Hub.
 *
 * @param string|null $token Токен из POST-запроса.
 * @param string|null $ip IP-адрес пользователя.
 * @return bool True, если проверка пройдена, иначе false.
 */
function isCaptchaValid(?string $token, ?string $ip): bool
{
    if (!$token) {
        return false;
    }

    $url = 'https://cphub.ru/api/v1/verify';
    $data = http_build_query([
        'secret' => CPHUB_SECRET_KEY,
        'token'  => $token,
        'ip'     => $ip,
    ]);

    // Инициализация cURL
    $ch = curl_init();

    // Настройка опций cURL
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5); // Таймаут 5 секунд

    // Выполнение запроса
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);

    // Обработка ошибок сети
    if ($curl_error) {
        // Если сервис капчи недоступен, временно пропускаем пользователя
        // и логируем ошибку для себя.
        error_log('Captcha Hub service error: ' . $curl_error);
        return true;
    }

    // Проверка ответа
    if ($http_code === 200) {
        $result = json_decode($response);
        return $result && $result->success === true;
    }

    return false;
}


// --- Пример использования ---

$user_token = $_POST['cphb-captcha-token'] ?? null;
$user_ip = $_SERVER['REMOTE_ADDR'] ?? null;

if (isCaptchaValid($user_token, $user_ip)) {
    // УСПЕХ: Пользователь — человек.
    echo "Проверка пройдена!";
} else {
    // ОШИБКА: Пользователь — бот.
    echo "Проверка не пройдена.";
}
Скопировано
<?php

//С использованием библиотеки - https://github.com/Website-Protection/cphub-verifier

//composer require website-protection/cphub-verifier

//php artisan vendor:publish --provider="WebsiteProtection\CaptchaHubVerifier\CaptchaHubVerifierServiceProvider" --tag="config"

//Добавьте ваш секретный ключ в файл .env
//CPHUB_SECRET_KEY=ВАШ_СЕКРЕТНЫЙ_КЛЮЧ

use Illuminate\Http\Request;
use WebsiteProtection\CaptchaHubVerifier\Facades\CaptchaHub;
use Illuminate\Validation\ValidationException;

class FormController extends Controller
{
    public function store(Request $request)
    {
        $token = $request->input('cphb-captcha-token');

        if (! CaptchaHub::verify($token)) {
            throw ValidationException::withMessages([
               'captcha' => 'Проверка на робота не пройдена.',
            ]);
        }

        // Успех! Логика обработки формы...
    }
}

//Без библиотеки

namespace App\Http-Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;

class FormController extends Controller
{
    /**
     * Пример обработки формы с проверкой капчи.
     */
    public function submit(Request $request)
    {
        // 1. Проверяем капчу
        if (! $this->isCaptchaValid($request)) {
            // Если проверка не пройдена, возвращаем ошибку валидации
            throw ValidationException::withMessages([
               'captcha' => 'Проверка на робота не пройдена. Попробуйте снова.',
            ]);
        }

        // УСПЕХ! Пользователь — человек.
        // Здесь ваша логика обработки формы...

        return back()->with('success', 'Форма успешно отправлена!');
    }

    /**
     * Отправляет токен на проверку в сервис Captcha Hub.
     */
    private function isCaptchaValid(Request $request): bool
    {
        $token = $request->input('cphb-captcha-token');

        if (!$token) {
            return false;
        }

        try {
            // Используем HTTP-клиент Laravel для отправки запроса
            $response = Http::asForm()
                ->timeout(5) // Устанавливаем таймаут в 5 секунд
                ->post('https://cphub.ru/api/v1/verify', [
                    'secret' => config('services.cphub.secret'), // Ключ из config/services.php
                    'token' => $token,
                    'ip' => $request->ip(),
                ]);

            // Проверяем, что запрос успешен И в ответе есть {"success": true}
            return $response->successful() && $response->json('success') === true;

        } catch (\Exception $e) {
            // Если сервис Captcha Hub недоступен, логируем ошибку,
            // но пропускаем пользователя, чтобы не блокировать работу сайта.
            Log::error('Captcha Hub service is unavailable.', ['error' => $e->getMessage()]);
            return true; // Временно разрешаем доступ
        }
    }
}
                                    
                                
Скопировано
import requests
import os

# --- Ваши данные ---
# Секретный ключ лучше хранить в переменных окружения, а не в коде
secret_key = os.environ.get('CAPTCHA_SECRET_KEY', 'ВАШ_SECRET_KEY')
# Токен, полученный из формы
token = request.form.get('cphb-captcha-token')
# IP-адрес пользователя (зависит от вашего фреймворка, например, Flask)
user_ip = request.remote_addr

# --- Отправка запроса на проверку ---
api_url = 'https://cphub.ru/api/v1/verify'
payload = {
    'secret': secret_key,
    'token': token,
    'ip': user_ip
}

try:
    response = requests.post(api_url, data=payload, timeout=5)
    response.raise_for_status() # Вызовет ошибку, если код ответа не 2xx

    result = response.json()

    if result.get('success'):
        # УСПЕХ: Пользователь — человек.
        # Продолжаем обработку формы (например, сохраняем комментарий).
        print("Проверка пройдена!")
    else:
        # ОШИБКА: Пользователь — бот.
        # Показываем ошибку.
        error_codes = result.get('error-codes', [])
        print(f"Проверка не пройдена: {error_codes}")

except requests.exceptions.RequestException as e:
# Ошибка сети или сервер недоступен
print(f"Ошибка подключения к сервису капчи: {e}")
                                    
                                
Скопировано
const axios = require('axios');
const querystring = require('querystring');

// --- Ваши данные ---
// Секретный ключ лучше хранить в переменных окружения
const secretKey = process.env.CAPTCHA_SECRET_KEY || 'ВАШ_SECRET_KEY';
// Токен, полученный из тела запроса (зависит от вашего фреймворка, например, Express)
const token = req.body['cphb-captcha-token'];
// IP-адрес пользователя
const userIp = req.ip;

// --- Отправка запроса на проверку ---
const apiUrl = 'https://cphub.ru/api/v1/verify';
const payload = {
    secret: secretKey,
    token: token,
    ip: userIp
};

async function verifyCaptcha() {
    try {
        const response = await axios.post(apiUrl, querystring.stringify(payload), {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            timeout: 5000 // таймаут 5 секунд
        });

        if (response.data && response.data.success) {
            // УСПЕХ: Пользователь — человек.
            // Продолжаем обработку (например, res.send('Success!')).
            console.log('Проверка пройдена!');
        } else {
            // ОШИБКА: Пользователь — бот.
            const errorCodes = response.data['error-codes'] || [];
            console.log(`Проверка не пройдена: ${errorCodes.join(', ')}`);
        }
    } catch (error) {
        // Ошибка сети или сервер недоступен
        console.error('Ошибка подключения к сервису капчи:', error.message);
    }
}

verifyCaptcha();
                                    
                                
Скопировано

Справочник API: Метод Verify

Эндпоинт для сервер-серверной проверки токена

POST https://cphub.ru/api/v1/verify

Параметры (application/x-www-form-urlencoded):

ПараметрТипОписание
secretstringОбязательный Ваш приватный Secret Key
tokenstringОбязательный Значение из поля cphb-captcha-token
ipstringРекомендуется IP-адрес конечного пользователя для более точной проверки

Пример успешного ответа (200 OK):

{
  "success": true
}
Скопировано

Коды ошибок

В случае неудачной проверки, в JSON-ответе будет поле error-codes с массивом строк

Код ошибкиОписание
invalid-secret-keyОтправлен неверный или несуществующий Secret Key
timeout-or-duplicateТокен не найден, его время жизни истекло, или он уже был использован
invalid-input-response(Зарезервировано) Ответ пользователя был некорректным