Что такое CAPTCHA и зачем она нужна вашему сайту
CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) — это механизм «испытание–ответ», который пытается отличить реальных пользователей от автоматизированных скриптов. Современные решения варьируются от традиционных головоломок с искажённым текстом до невидимого поведенческого анализа и интерактивных задач, таких как слайдер GeeTest.
Без слоя CAPTCHA любая публичная форма на вашем сайте становится уязвимой к:
- Credential stuffing — автоматизированным попыткам входа с использованием утёкших пар «логин/пароль», что часто встречается в абьюз‑трафике.
- Spam submissions — ботам, которые засыпают формы обратной связи, разделы комментариев или страницы отзывов.
- Account enumeration — скриптам, которые «прощупывают» валидные email‑адреса или имена пользователей.
- Scraping — автоматизированному извлечению цен, складских остатков или проприетарного контента.
Компромисс всегда один - безопасность vs. пользовательский опыт: прерывание действий пользователя останавливает ботов, но слишком много неудобства отталкивает реальных пользователей. Cloudflare Turnstile и GeeTest v3 — современные варианты CAPTCHA, которые стараются сбалансировать эти аспекты: Turnstile ориентирован на проверку с минимальным неудобством, а GeeTest v3 использует интерактивные задачи разных типов с поведенческими проверками для обнаружения ботов.
Как получить ваш CAPTCHA Code (ключи и учётные данные)
Прежде чем писать какой-либо код интеграции, вам понадобятся учётные данные, специфичные для конкретного провайдера CAPTCHA.
GeeTest V3
- Создайте аккаунт в панели GeeTest.
- Перейдите в Captcha Dashboard и выберите CAPTCHA v3:

- Перейдите в раздел, где можно создать новую CAPTCHA и зарегистрировать ваш сайт (обычно указывают домены и тип продукта).
- После настройки вы получите CAPTCHA ID (часто обозначается как gt) и приватный Key для серверного взаимодействия.
- Храните эти значения безопасно (например, в переменных окружения), чтобы приложение могло использовать их без хардкода секретов.
Cloudflare Turnstile
- Войдите на dash.cloudflare.com и откройте раздел Application security > Turnstile.

- Нажмите Add widget, введите ваш домен и выберите режим виджета: Managed, Non-interactive или Invisible.
- Установите Pre-clearance в Yes , если сайт работает через Cloudflare Proxy (чтобы избежать повторного показа CAPTCHA).
- После создания Cloudflare выдаёт Site Key (публичный, используется на клиенте) и Secret Key (приватный, используется на сервере).
- Используйте Site Key в вашем HTML или JavaScript, а Secret Key отправляйте только с бэкенда при вызове Turnstile verification API.
Как внедрить GeeTest CAPTCHA v3: пошаговая инструкция
GeeTest v3 использует многошаговый процесс: ваш server получает свежий challenge от GeeTest, затем client отрисовывает задачу, используя этот challenge (GeeTest API1), и после этого ваш server проверяет решённые токены (GeeTest API2). Ниже приведён пример реализации на PHP + JavaScript, иллюстрирующий этот паттерн; адаптируйте его под официальный SDK GeeTest и выбранный вами язык.
Шаг 1 — эндпоинт регистрации на стороне сервера
Создайте PHP-скрипт (например, geetest_register.php), который получает свежий challenge от GeeTest и передаёт его клиенту:
<?php
header('Content-Type: application/json');
const CAPTCHA_ID = '07df3141a35**19a473d7c50';
const CAPTCHA_KEY = '543b19036ef**8e07d121b81e9';
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
function getJson($url) {
$res = @file_get_contents($url);
return $res ? json_decode($res, true) : null;
}
// API1: Инициализация
if ($path === '/register') {
$data = getJson("https://api.geetest.com/register.php?gt=" . CAPTCHA_ID . "&json_format=1");
echo json_encode($data ? [
'gt' => CAPTCHA_ID,
'challenge' => $data['challenge'],
'success' => $data['success'] === 1,
'new_captcha' => true
] : ['success' => 0]);
exit;
}
// API2: Верификация
if ($path === '/validate' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$req = json_decode(file_get_contents('php://input'), true);
$data = getJson("https://api.geetest.com/validate.php?" . http_build_query([
'seccode' => $req['geetest_seccode'] ?? '',
'challenge' => $req['geetest_challenge'] ?? '',
'gt' => CAPTCHA_ID,
'json_format' => 1
]));
echo json_encode(['success' => !empty($data['seccode'])]);
exit;
}
http_response_code(404);
echo json_encode(['error' => 'Not found']);
Шаг 2 — инициализация на стороне клиента
Подключите SDK GeeTest и вызовите initGeetest, передав параметры с сервера (API1). Пример с использованием ajax:
ajax({
url: "https://example.com/register",
type: "get",
dataType: "json",
success: function (data) {
initGeetest({
gt: data.gt,
challenge: data.challenge,
offline: !data.success,
new_captcha: true
}, function (captchaObj) {
captchaObj.appendTo("#captcha");
captchaObj.onSuccess(function () {
const result = captchaObj.getValidate();
ajax({
url: "https://example.com/validate",
type: "post",
contentType: "application/json",
data: JSON.stringify(result),
success: function(res) {
if (res.success) alert('CAPTCHA passed');
else alert('CAPTCHA failed');
}
});
});
});
}
});
Проверка работы
Убедитесь, что:
- /register возвращает challenge
- Капча отображается корректно
- После прохождения капчи запрос на /validate виден в консоли браузера
- Сервер возвращает "success": true
Failback (режим fallback)
Если сервер GeeTest недоступен:
- Клиент получает success: false
- Капча переключается в локальный режим (работает без подключения к GeeTest Cloud). Чтобы проверить это, просто подставьте некорректный CAPTCHA_ID (например, 123456789).
Примечание: GeeTest также предоставляет официальные server-side SDK для разных платформ и языков — вы можете выбрать тот, который соответствует вашему технологическому стеку. Подробнее — в официальной документации GeeTest CAPTCHA v3.
Как внедрить Cloudflare Turnstile: пошагая инструкция
У Cloudflare Turnstile нет отдельного серверного «registration call». Вы встраиваете виджет на страницу, позволяете ему сгенерировать токен, а затем проверяете этот токен на стороне сервера через Siteverify API от Cloudflare.
Шаг 1 — Подключите скрипт Turnstile
Автоматический рендеринг (виджет создаётся автоматически при загрузке страницы):
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
Программное управление (вы создаёте виджет самостоятельно через JavaScript):
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit" defer></script>
Важно: скрипт должен быть загружен с точного URL. Прокси или кэш могут привести к сбоям.
Шаг 2 — Создайте контейнер для виджета
Авто:
<div class="cf-turnstile" data-sitekey="<YOUR_SITEKEY>"></div>
Программно:
<div id="turnstile-container"></div>
Шаг 3 — Настройка виджета
Через data-атрибуты:
<div class="cf-turnstile" data-sitekey="<YOUR_SITEKEY>" data-theme="light" data-size="normal" data-callback="onSuccess"> </div>
Через JavaScript:
const widgetId = turnstile.render("#turnstile-container", {
sitekey: "<YOUR_SITEKEY>",
theme: "light",
size: "normal",
callback: token => console.log("Token:", token)
});
Шаг 4 — Работа с токенами
const token = turnstile.getResponse(widgetId); // получение токена
const isExpired = turnstile.isExpired(widgetId); // проверка срока действительности токена
turnstile.reset(widgetId); // сброс
turnstile.remove(widgetId); // удаление
turnstile.execute("#turnstile-container"); // ручное извлечение
Шаг 5 — Интеграция с формой
<form id="my-form" method="POST">
<input type="hidden" name="cf-turnstile-response" id="cf-turnstile-response">
<button type="submit">Submit</button>
</form>
<script>
function onSuccess(token) {
document.getElementById("cf-turnstile-response").value = token;
}
</script>
Полный пример кода
<html>
<title>Turnstile Example</title> <!-- Подключение скрипта Turnstile -->
<head>
<script src="https: //challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>
<h1>Form example with Turnstile</h1>
<form id="my-form"> <label for="username">Name:</label> <input type="text" name="username" id="username" required> <!-- Контейнер для Turnstile -->
<div class="cf-turnstile" data-sitekey="<YOUR_SITEKEY>" data-callback="onTurnstileSuccess"></div> <button type="submit">Submit</button>
</form>
<script>
// Callback, вызываемый после прохождения CAPTCHA
function onTurnstileSuccess(token) {
console.log("Received Turnstile token:", token);
// Save token to hidden form field (optional)
document.getElementById("cf-turnstile-token") ? .remove();
const input = document.createElement("input");
input.type = "hidden";
input.name = "cf-turnstile-response";
input.id = "cf-turnstile-token";
input.value = token;
document.getElementById("my-form").appendChild(input);
}
// Отправка формы
document.getElementById("my-form").addEventListener("submit", async(e) => {
e.preventDefault();
const formData = new FormData(e.target);
const response = await fetch("/submit-form", {
method: "POST",
body: formData
});
const result = await response.json();
if(result.success) {
alert("Form successfully submitted and token verified!");
}
else {
alert("Turnstile token verification error. Please try again.");
// Reset widget so the user can complete the CAPTCHA again
turnstile.reset();
}
});
</script>
</body>
</html>
Шаг 6 — Настройте серверную часть
Процесс проверки на стороне сервера:
- Клиент: пользователь проходит Turnstile на странице → создаётся токен.
- Форма отправляется: токен вместе с данными формы отправляется на сервер.
- Сервер: делает POST-запрос к Cloudflare Siteverify API с токеном и секретом.
- Cloudflare: возвращает JSON с результатом (success: true/false) и дополнительной информацией (action, hostname, completion time).
- Сервер: решает, разрешить или отклонить действие пользователя.
Siteverify API:
POST
https://challenges.cloudflare.com/turnstile/v0/siteverify
Параметры запроса:
- secret (обязательно): секретный ключ Turnstile из панели Cloudflare
- response (обязательно): токен, полученный на клиенте
- remoteip (необязательно): IP-адрес пользователя (рекомендуется)
- idempotency_key (необязательно): уникальный UUID для защиты от повторных верификаций
Свойства токена:
- Максимальная длина: 2048 символов
- Действителен 5 минут
- Одноразовый (single-use)
- При истечении срока действия или повторной верификации API вернёт ошибку timeout-or-duplicate
Пример проверки на PHP:
<?php
function validateTurnstile($token, $secret, $remoteip = null) {
$url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
$data = ['secret' => $secret,
'response' => $token];
if ($remoteip) $data['remoteip'] = $remoteip;
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded
",
'method' => 'POST',
'content' => http_build_query($data)
]
];
$response = file_get_contents($url, false, stream_context_create($options));
if ($response === FALSE) {
return ['success' => false,
'error-codes' => ['internal-error']];
}
return json_decode($response, true);
}
$secret_key = 'YOUR_SECRET_KEY';
$token = $_POST['cf-turnstile-response'] ?? '';
$remoteip = $_SERVER['REMOTE_ADDR'];
$result = validateTurnstile($token, $secret_key, $remoteip);
if ($result['success']) {
echo "Form successfully submitted!";
} else {
echo "Verification error: " . implode(', ', $result['error-codes']);
}
?>
Примечание: Все подробные инструкции по установке и настройке Cloudflare Turnstile, включая клиентскую и серверную интеграцию, примеры кода, описания ошибок и рекомендации по безопасности, можно найти в официальной документации Cloudflare.
Создание собственной CAPTCHA: когда и зачем
Любая кастомная captcha — это система «задача–ответ», которую вы создаёте сами вместо интеграции стороннего сервиса. Распространённые лёгкие подходы включают:
- Math puzzles — «Сколько будет 4 + 9?», показанное как обычный текст или простое сгенерированное изображение.
- Honeypot fields — скрытые поля формы, которые обычно заполняют только боты.
- Time-based checks — отклонение отправок, выполненных нереалистично быстро для человека.
- Custom image challenges — «Выберите лишний предмет» с использованием ваших собственных ассетов.
Кастомные captcha могут быть полезны, когда вам нужен строгий контроль над брендингом, когда жёсткие требования к приватности ограничивают использование сторонних капч, или когда ваш риск‑профиль низкий и вам достаточно базовой защиты от ботов. Однако им обычно не хватает продвинутых поведенческих моделей сервисов вроде GeeTest или Turnstile, и их может быть проще «победить» продвинутым ботам.
Вы также берёте на себя полную ответственность за доступность капчи для людей с ограниченными возможностями (например, предоставление аудио‑альтернатив) и постоянное сопровождение по мере того, как эволюционируют техники ботов. Для критичных сценариев вроде логина, оформления заказа или сброса пароля управляемое стороннее решение обычно безопаснее полностью кастомной captcha.
Как эффективно блокировать CAPTCHA-ботов
Внедрение CAPTCHA необходимо, но редко бывает достаточным само по себе: целеустремлённые атакующие скрипты попытаются обойти её или автоматизировать. Чтобы эффективнее блокировать captcha‑ботов, комбинируйте несколько уровней.
Уровень 1 — Rate limiting на уровне инфраструктуры
Rate limiting на уровне веб‑сервера или CDN усложняет ботам перебор форм (brute force), даже если они умеют решать или обходить captcha. Например, в Nginx:
# Nginx: limit login endpoint to 10 req/s per IP
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/s;
location /login {
limit_req zone=login burst=5 nodelay;
# proxy_pass ...
}
Уровень 2 — Honeypot-поля
Скрытое поле, которого реальные пользователи никогда не видят, но которое могут заполнить несложные боты, — это защита с минимальным неудобством для пользователя.
<div aria-hidden="true">
<input type="text" name="website" tabindex="-1" autocomplete="off">
</div>
На сервере отклоняйте любую отправку, где name="website". Это почти не влияет на UX и при этом отфильтровывает часть автоматизированных отправок.
Уровень 3 — Дополнительные слои защиты
- IP reputation filtering: блокирование известных диапазонов дата‑центров или сервисов анонимизации может существенно сократить абьюз‑трафик.
- Token replay prevention: токены Turnstile необходимо валидировать на стороне сервера и считать одноразовыми; отбрасывание повторно используемых токенов помогает предотвращать replay‑атаки.
- Device or session fingerprinting: внешние инструменты могут помочь коррелировать подозрительные паттерны между IP и сессиями, хотя это заставляет проверить политику приватности.
- Monitoring and alerting: отслеживайте долю неуспешных проверок и резкие всплески трафика из конкретных регионов или ASN как сигналы продолжающейся атаки.