Безопасный scope: Это руководство применимо только к собственным или явно авторизованным QA-, staging- и production-средам. Описаны сценарии диагностики, тестирования и наблюдаемости вашей собственной CAPTCHA-интеграции — не для сторонних сайтов и не для несанкционированных workflow.
Единого «хорошего» score reCAPTCHA v3 не бывает — есть порог, который вы задаёте сами под конкретный action, глядя на реальное распределение в своём приложении. Типичная ошибка не в самом score, а в том, что одну и ту же границу применяют сразу к login, signup и checkout, хотя у каждого сценария своя естественная кривая. Ниже — как разложить score по action, подобрать threshold без гадания и добавить fallback, который не отсекает легитимных пользователей.
Зачем считать score отдельно по action
reCAPTCHA v3 возвращает score от 0.0 до 1.0 для каждого вызова grecaptcha.execute, и этот score привязан к конкретному action. Каждое значимое действие должно получать собственный action: login, signup, checkout, password_reset. Один общий action на всё приложение смешивает распределения разных по природе сценариев — под такую смесь невозможно подобрать адекватный threshold, потому что high-risk форма (например, signup) тянет общий медианный score вниз, а низкорисковая (login для постоянных пользователей) — вверх.
Как собрать распределение score
Прежде чем выбирать порог, накопите сырые значения по каждому action хотя бы за неделю трафика:
from collections import defaultdict
scores = defaultdict(list)
def record(action: str, score: float) -> None:
scores[action].append(score)
def below(action: str, threshold: float) -> float:
values = scores.get(action, [])
if not values:
return 0.0
return sum(1 for v in values if v < threshold) / len(values)
Функция below сразу даёт долю запросов, которые упадут ниже кандидата на threshold, — по ней и подбирается граница, а не «на глаз».
С каких порогов начинать
Это стартовые значения, а не финальные — используйте их как отправную точку, а после первой недели данных скорректируйте по функции below:
- login — 0.5, устойчиво для известных пользователей.
- signup — 0.5–0.7, распределение сильнее зашумлено.
- checkout — 0.5–0.7, здесь особенно важна стабильность UX.
- password_reset — 0.3–0.5, щадящий threshold, чтобы не блокировать людей, забывших пароль.
Мягкий fallback вместо жёсткого отказа
Если score ниже threshold, не отказывайте в доступе сразу. Включайте дополнительный шаг — reCAPTCHA v2, подтверждение по e-mail или 2FA. Жёсткий блок на пограничном score почти всегда бьёт по легитимным пользователям сильнее, чем по автоматизации: боты просто уходят в другой сценарий, а обычный человек с нетипичным поведением (новая сеть, VPN на работе, непривычное устройство) остаётся заблокирован.
QA-тестирование интеграции с CaptchaAI
Для воспроизводимых QA-сценариев в собственной staging-среде используйте CaptchaAI: получите токен, верифицируйте его на собственном backend и запишите фактический score в журнал рядом с action и окружением. Это даёт контрольную точку — вы видите, как ведёт себя пайплайн проверки токена независимо от поведенческих факторов конкретного браузера.
Логи, дашборд и региональный срез
Структурированные логи позволяют сравнивать поведение CAPTCHA между релизами и быстро находить регрессии в собственных формах:
import json, time, logging
log = logging.getLogger('captcha-qa')
def record(event: str, **fields) -> None:
payload = {'ts': time.time(), 'event': event, **fields}
log.info(json.dumps(payload, ensure_ascii=False))
Минимальный набор полей для каждой попытки: slug, captcha_type, task_id, wait_seconds, verify_status, env. Этого достаточно, чтобы построить дашборд медианы, P90 и P99 по типу CAPTCHA и по среде.
Для команд, чья аудитория распределена между Россией, Беларусью, Казахстаном и Украиной, полезно добавить в тот же дашборд срез по региону деплоя или по локали запроса. На практике распределение score нередко расходится между европейскими регионами хостинга и площадками в Казахстане или Центральной Азии — из-за разной сетевой репутации диапазонов IP и разного профиля мобильного трафика. Без региональной сегментации такую разницу легко принять за баг интеграции, хотя это особенность самого score.
Частые проблемы и что проверить
| Симптом | Что сделать |
|---|---|
| Стабильно низкий score | Проверьте action и сессию |
| Скачки распределения | Проверьте версии и инициализацию v3 |
| Много fallback-шагов | Снизьте threshold |
| Расхождение между регионами | Сегментируйте дашборд по локали |
QA-чек-лист перед релизом
- Запрос отправляется только на собственные или авторизованные endpoints.
- Тестовые учётные записи, события и платежи помечены как фиктивные и не содержат реальных персональных данных — это важно и с точки зрения 152-ФЗ «О персональных данных», и для команд с трансграничной аудиторией, где применяется должная осмотрительность по GDPR.
- CAPTCHA-токен проверяется на собственном backend, а не доверяется клиенту.
- Логи содержат
task_id, тип CAPTCHA, время ожидания и pass/fail. - Скрипт возвращает корректный exit code, чтобы CI мог принять решение.
FAQ
Как выбрать стартовый threshold для нового action?
Начните с диапазона из списка выше, соберите распределение хотя бы за неделю и посчитайте функцией below, какая доля запросов попадёт под кандидата на порог. Если доля fallback-шагов кажется высокой, сдвиньте threshold ниже, а не отказывайте пользователям жёстко.
Что делать, если распределение score резко изменилось после деплоя?
Сравните версию reCAPTCHA v3 и место инициализации виджета — чаще всего причина в том, что action перестал передаваться корректно или скрипт грузится не на той странице. Сверьте логи task_id и verify_status до и после релиза на одинаковой выборке сценариев.
Нужно ли валидировать токен на backend, если score высокий?
Да, всегда. Высокий score не заменяет проверку токена на вашем сервере — это разные механизмы: score оценивает поведение, а верификация токена подтверждает, что он не подделан и не переиспользован.
Как быстро включать fallback, чтобы не терять пользователей?
Держите порог fallback чуть выше жёсткого порога отказа и запускайте дополнительный шаг сразу, как только score попадает в пограничную зону, а не после повторной неудачной попытки. Это снижает число пользователей, которые уходят, не дождавшись второго шага.
Можно ли использовать один threshold для всех языковых версий приложения?
Не рекомендуется. Профиль трафика по региону деплоя и локали часто отличается — см. раздел про региональный срез выше. Начните с общего порога, но заложите возможность сегментировать его позже, если дашборд покажет устойчивую разницу.
Безопасные связанные руководства
- Быстрый старт CaptchaAI
- QA-тестирование CAPTCHA в авторизованных средах
- Тестирование CAPTCHA API на собственных формах
- Отладка: браузерный тест падает, API проходит
- reCAPTCHA v2 через API
- Cloudflare Turnstile через API
- GeeTest v3 через API
Стабильный UX и предсказуемый score в собственной app — начните с CaptchaAI.