Безопасный scope: это руководство применимо только к собственным или явно авторизованным QA-, staging- и production-средам. Ниже описаны диагностика, тестирование и наблюдаемость вашей собственной CAPTCHA-интеграции — не сторонние сайты и не несанкционированные workflow.
Каждый повторный вызов in.php при ретрае — это не только лишняя задержка, но и впустую занятый поток тарифа. Если запрос идемпотентен, а токен, полученный на предыдущей попытке, ещё не истёк по TTL, backend может отдать уже готовый токен вместо того, чтобы решать CAPTCHA заново. Ниже — когда это безопасно, как хранить токен в кеше и как связать это с идемпотентными ретраями.
Когда переиспользование токена оправдано
Кешировать и отдавать один и тот же токен повторно имеет смысл, когда:
- запрос идемпотентен — это тот же самый вызов, повторённый из-за таймаута или разрыва соединения, а не новое действие пользователя;
- сработал кратковременный сетевой сбой и backend делает retry на транспортном уровне;
- запись транзакционна, и слой ретраев на backend уже гарантирует, что один и тот же токен не попадёт в два разных заказа.
Переиспользование недопустимо между разными пользователями, разными действиями и разными формами — токен привязан к конкретному запросу, и это единственный безопасный контекст для повторной отправки.
На практике ретраи чаще всего возникают не из-за багов в коде, а из-за нестабильной мобильной сети у конечного пользователя — типичная ситуация для мобильного трафика в регионах СНГ и Центральной Азии. Правильный TTL-кеш превращает такой повтор запроса в дешёвую операцию, а не в новый вызов API.
TTL токенов по типам CAPTCHA
| Тип CAPTCHA | Типичный TTL | Особенность |
|---|---|---|
| reCAPTCHA v2 | около 120 с | один токен — одно действие |
| reCAPTCHA v3 | около 120 с | имя action привязано к токену |
| Cloudflare Turnstile | до 5 мин | токен одноразовый после проверки |
| hCaptcha | около 120 с | токен одноразовый |
TTL задаёт провайдер CAPTCHA, а не CaptchaAI, и точные значения стоит перепроверять в его актуальной документации — они периодически меняются. В кеше всегда закладывайте запас в 10–20 секунд от заявленного TTL, чтобы не отдать токен, который истечёт по дороге к проверяющему серверу.
Минимальный кеш в собственном backend
Для одного инстанса достаточно словаря с временем истечения на каждый ключ:
import time
_cache = {}
TTL = 110
def remember(key: str, token: str) -> None:
_cache[key] = (token, time.time() + TTL)
def get(key: str) -> str | None:
item = _cache.get(key)
if not item:
return None
token, expires = item
if time.time() >= expires:
_cache.pop(key, None)
return None
return token
Ключом кеша должен быть идентификатор конкретного запроса (sitekey + pageurl + идентификатор попытки), а не сам токен — иначе повторный поиск по кешу не сработает.
Idempotency-Key против двойного списания потока
Передавайте заголовок Idempotency-Key вместе с токеном при отправке формы на собственный backend. Если backend получает тот же ключ повторно, он возвращает результат уже проверенного токена и не запрашивает у CaptchaAI новое решение. Это защищает от двух проблем сразу: от повторного списания потока тарифа и от гонки, когда два одинаковых ретрая независимо проходят проверку и создают два заказа вместо одного.
Экономия ощутимее всего на высоконагруженных пайплайнах: на тарифе BASIC ($15/мес, 5 потоков) один лишний ретрай — это заметная доля ёмкости, а на ADVANCE ($90/мес, 50 потоков) устойчивый поток дублирующихся ретраев без Idempotency-Key может тихо съедать несколько потоков впустую.
Логи и наблюдаемость
Структурированные логи помогают сравнивать поведение 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 и по среде. Если в тестовые сценарии попадают данные реальных пользователей, помните про требования 152-ФЗ (или аналогичные требования вашей юрисдикции) — логируйте только данные фиктивных тестовых аккаунтов, помеченных как такие.
Типичные проблемы
| Симптом | Что сделать |
|---|---|
| Токен невалиден на ретрае | Уменьшите TTL в кеше, добавьте запас |
| Двойные списания у клиента | Проверьте, что Idempotency-Key действительно уникален на запрос |
| Кеш растёт неограниченно | Включите периодическую очистку по expiry |
| После рестарта кеш пуст | Перейдите на Redis с TTL вместо памяти процесса |
Чек-лист перед деплоем
- Запросы уходят только на собственные или авторизованные endpoints.
- Тестовые учётные записи, события и платежи явно помечены как фиктивные.
- CAPTCHA-токен проверяется на собственном backend, а не принимается со слов клиента.
- Логи содержат
task_id, тип CAPTCHA, время ожидания и итоговый статус. - Скрипт возвращает корректный exit code, чтобы CI мог принять решение по сборке.
Частые вопросы
Сколько живёт токен Cloudflare Turnstile в кеше?
До 5 минут по заявленному TTL, но закладывайте запас: храните токен в кеше на 4–4,5 минуты, а не на полный срок, чтобы исключить гонку между истечением и проверкой на стороне сервера.
Как избежать двойного списания потока при ретрае?
Свяжите каждый исходный запрос с Idempotency-Key и проверяйте его на backend перед тем, как обращаться к CaptchaAI заново. Если ключ уже встречался и токен ещё валиден по TTL, отдавайте сохранённый результат.
Нужен ли Redis, если TTL токена — всего пара минут?
Для одного инстанса достаточно памяти процесса. Redis становится нужен, как только сервисов или воркеров больше одного — иначе рестарт или деплой одного инстанса обнуляет кеш, и соседний инстанс не увидит уже решённый токен.
Что делать, если CaptchaAI вернул ошибку при повторном решении?
Логируйте task_id, тип CAPTCHA и текст ошибки, повторите запрос с экспоненциальной задержкой и фиксируйте долю ошибок в дашборде. Устойчивый рост ошибок — повод проверить sitekey и целевую страницу, а не сразу увеличивать таймаут.
Можно ли использовать этот подход на сторонних сайтах?
Нет. Кеш и повторное использование токена применимы только к собственным или явно авторизованным средам. Для чужих ресурсов нужно письменное разрешение владельца сайта.
Безопасные связанные руководства
- Быстрый старт CaptchaAI
- QA-тестирование CAPTCHA в авторизованных средах
- Тестирование CAPTCHA API на собственных формах
- Отладка: браузерный тест падает, API проходит
- reCAPTCHA v2 через API
- Cloudflare Turnstile через API
- GeeTest v3 через API
Настройте TTL-кеш и Idempotency-Key для своего backend — подключите CaptchaAI.