KryaCaptcha (КряКапча) — это продвинутый антибот-модуль и саркастичное испытание в стиле World's Hardest CAPTCHA на русском языке.
Поддерживает встраивание в HTML-формы через JS SDK (kryacaptcha.js) и серверную валидацию через REST API.
Добавьте скрипт в разметку вашей страницы и укажите контейнер:
<!-- 1. Подключение скрипта -->
<script src="http://localhost:3000/sdk/kryacaptcha.js"></script>
<!-- 2. Контейнер капчи внутри вашей формы -->
<form action="/login" method="POST">
<input type="text" name="username" placeholder="Логин" />
<input type="password" name="password" placeholder="Пароль" />
<div id="captcha-box"></div>
<button type="submit">Войти</button>
</form>
<!-- 3. Инициализация виджета -->
<script>
const widget = KryaCaptcha.render('#captcha-box', {
mode: 'rounds', // 'rounds' или 'endless'
targetRounds: 3, // количество раундов до победы
onSuccess: function(token) {
console.log('Пользователь доказал человечность! Токен:', token);
},
onFail: function(stats) {
console.log('Капча провалена:', stats);
}
});
</script>
При успешном прохождении скрипт автоматически заполняет скрытое поле <input type="hidden" name="hardcaptcha-token" /> внутри формы.
После отправки формы ваш бэкенд проверяет полученный токен через эндпоинт /api/v1/siteverify (совместимо со стандартом Cloudflare Turnstile и Google reCAPTCHA).
Токен одноразовый (повторная проверка вернёт error-codes: ["timeout-or-duplicate"]) и живёт 1 час.
Секрет сервиса задаётся переменной окружения HARDCAPTCHA_SECRET и в запросе не передаётся.
Ответ содержит и success, и синоним valid; провал проверки — это HTTP 200 с success: false.
/api/v1/siteverify| Параметр | Тип | Описание |
|---|---|---|
token |
string (обязательный) | Подписанный HMAC токен из поля формы hardcaptcha-token. |
bind |
string (опционально) | Контекст, к которому привязан токен (например user:12345). Должен совпадать с тем, что виджет передал в опции bind, иначе токен не будет принят. |
min_rounds |
number (опционально) | Минимальное число пройденных раундов. Число раундов задаётся на клиенте, поэтому требуемый минимум проверяйте здесь. |
Пример ответа сервера:
{
"success": true,
"score": 1.0,
"rounds_completed": 3,
"mode": "rounds",
"challenge_ts": "2026-09-03T20:15:30.123Z",
"action": "hardcaptcha_verify"
}
app.post('/login', async (req, res) => {
const token = req.body['hardcaptcha-token'];
const verifyRes = await fetch('http://localhost:3000/api/v1/siteverify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token })
});
const data = await verifyRes.json();
if (data.success) {
res.send('Успешный вход! Человечность подтверждена.');
} else {
res.status(403).send('Ошибка капчи: роботам вход воспрещен.');
}
});
import requests
def verify_kryacaptcha(token: str) -> bool:
resp = requests.post(
"http://localhost:3000/api/v1/siteverify",
json={"token": token}
)
result = resp.json()
return result.get("success", False)
Большинство заданий сервер рисует сам и отдаёт полем image (data-URI, PNG или JPEG);
у заданий с анимацией вместо него массив frames и расписание показа playlist.
Правильный ответ в задании не передаётся — его знает только сервер, поэтому решить головоломку
можно, лишь распознав картинку. Клиент отправляет на /verify действие пользователя:
номер квадрата, число, угол доворота, позицию фрагмента, последовательность нажатий.
/api/v1/session/newСоздаёт новую сессию капчи.
curl -X POST http://localhost:3000/api/v1/session/new \
-H "Content-Type: application/json" \
-d '{"mode": "rounds", "targetRounds": 3, "bind": "user:12345"}'
targetRounds зажимается сервером в диапазон 1–20. Опциональный bind привязывает
будущий токен к пользователю или действию — то же значение затем передаётся в /siteverify.
Опциональный progressSteps (массив до 64 чисел, например [0, 50, 80, 95, 99, 99.9])
задаёт свои ступени процента «человечности» для режима endless: по одному значению на пройденный
раунд, дальше процент сам ползёт к 100%, не достигая его. Это только оформление — в бесконечном режиме
токен не выдаётся вовсе, а в режиме rounds параметр игнорируется, чтобы процент по-прежнему
показывал реальный прогресс до выдачи токена.
/api/v1/session/:sessionId/challenge
Возвращает текущую задачу сессии (повторный вызов не выдаёт новую — это сброс этапа, а не пропуск).
Параметр ?forceType=chess предназначен для отладки: он подставляет конкретную головоломку и
переводит сессию в тренировочный режим, токен такой сессии /siteverify не примет
(error-codes: ["practice-session"]). То же касается включённого бессмертия.
/api/v1/session/:sessionId/verifyОтправляет ответ пользователя на проверку движку сессии.