Введение
Captcha Hub — это адаптивная система защиты, разработанная для обеспечения безопасности веб-форм при минимальном вмешательстве в пользовательский опыт. Наша цель — эффективно блокировать ботов, оставаясь практически незаметными для реальных пользователей
Как это работает
Процесс проверки полностью автоматизирован и состоит из нескольких этапов:
- Инициализация виджета: На вашем сайте загружается наш легковесный JS-скрипт, который отрисовывает виджет "Я не робот"
- Пассивный анализ: В фоне скрипт собирает сотни анонимных поведенческих и технических сигналов (движение мыши, ритм нажатий, отпечаток браузера, репутация IP)
- Решение в реальном времени: Когда пользователь нажимает на чекбокс, собранные данные отправляются на наш сервер. Наша скоринговая модель мгновенно принимает решение
- Дополнительное задание (Challenge): Только если система не уверена в пользователе, ему будет показано простое дополнительное задание (например, ввести текст с картинки)
- Получение токена: После успешной проверки наш скрипт помещает одноразовый токен в скрытое поле вашей формы
- Серверная верификация: Ваш бэкенд отправляет этот токен и ваш `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
Эндпоинт для сервер-серверной проверки токена
Параметры (application/x-www-form-urlencoded):
Параметр | Тип | Описание |
---|---|---|
secret | string | Обязательный Ваш приватный Secret Key |
token | string | Обязательный Значение из поля cphb-captcha-token |
ip | string | Рекомендуется IP-адрес конечного пользователя для более точной проверки |
Пример успешного ответа (200 OK):
{
"success": true
}
Скопировано
Коды ошибок
В случае неудачной проверки, в JSON-ответе будет поле error-codes
с массивом строк
Код ошибки | Описание |
---|---|
invalid-secret-key | Отправлен неверный или несуществующий Secret Key |
timeout-or-duplicate | Токен не найден, его время жизни истекло, или он уже был использован |
invalid-input-response | (Зарезервировано) Ответ пользователя был некорректным |