Cloudflare Turnstile: как устроен, что видит на вашей стороне и как его подключить — пошаговый гайд
Содержание статьи
- Введение: что вы получите от этого гайда
- Предварительная подготовка: инструменты и доступы
- Базовые понятия: как устроен cloudflare turnstile
- Шаг 1: разбираемся, что именно turnstile видит с вашей стороны
- Шаг 2: создаём виджет в панели cloudflare
- Шаг 3: встраиваем виджет на страницу с формой
- Шаг 4: настраиваем серверную проверку токена
- Шаг 5: тестируем виджет во всех режимах с тестовыми ключами
- Шаг 6: смотрим на turnstile глазами посетителя через мобильные прокси
- Проверка результата: итоговый чек-лист
- Типичные ошибки и их решения
- Дополнительные возможности для продвинутых
- Faq: частые вопросы по cloudflare turnstile
- Заключение
Введение: что вы получите от этого гайда
Cloudflare Turnstile — это тот самый небольшой виджет с крутящимся кружком и надписью «Verifying», который всё чаще встречается вместо привычной капчи с картинками. Он стоит на формах регистрации, в корзинах интернет-магазинов, на лендингах и в личных кабинетах сервисов. Обычный посетитель его почти не замечает. А вот для маркетолога, арбитражника или разработчика, который работает через мобильные прокси и открывает десятки сайтов в день, он превращается в загадку. Почему на одном профиле проверка пролетает за секунду, а на другом виджет задумывается, просит поставить галочку или выдаёт код ошибки?
В этом гайде мы разберём Cloudflare Turnstile с двух сторон. Со стороны владельца сайта — вы своими руками подключите виджет на страницу, настроите серверную проверку и научитесь читать статистику. Со стороны посетителя — вы поймёте, какие именно сигналы собирает Turnstile, что он видит о вашем браузере, сети и прокси, и почему принимает то или иное решение. Это знание одинаково полезно и тем, кто защищает свои формы от ботов, и тем, кто хочет, чтобы его рабочие профили выглядели для проверки как обычные пользователи.
Для кого этот гайд
- Для владельцев бизнеса и маркетологов, у которых спам-заявки и фейковые регистрации портят статистику и съедают бюджет.
- Для разработчиков, которым нужно быстро и без ошибок встроить Turnstile в форму и правильно проверять токен на сервере.
- Для арбитражников и специалистов по мультиаккаунтингу, которые работают через мобильные прокси и хотят понимать, что видит Turnstile при их подключении.
Что нужно знать заранее
Специальных знаний не требуется. Достаточно понимать, что такое HTML-страница, уметь открыть консоль разработчика в браузере и иметь хотя бы минимальный опыт работы с любым языком на сервере — PHP, Node.js, Python. Если серверной части у вас нет, вы всё равно пройдёте большую часть гайда: виджет можно подключить и протестировать на локальной странице.
Сколько времени потребуется
Полное прохождение — около полутора-двух часов. Регистрация и создание виджета занимают 10-15 минут, встраивание на страницу — 20 минут, серверная проверка — 30-40 минут, тестирование и диагностика — ещё 30 минут. Теоретические разделы можно читать в любом порядке и возвращаться к ним по мере необходимости.
Предварительная подготовка: инструменты и доступы
Прежде чем начинать, соберите всё необходимое. Это избавит вас от пауз в середине процесса.
Необходимые инструменты и доступы
- Аккаунт Cloudflare. Бесплатный. Регистрируется по адресу электронной почты за пару минут. Домен на Cloudflare переносить не обязательно — Turnstile работает на любом сайте, где бы он ни хостился.
- Сайт или тестовая страница. Подойдёт любая HTML-страница с формой. Для локальных экспериментов достаточно файла на компьютере, открытого через простой локальный сервер.
- Серверная среда. Любой хостинг с PHP, либо Node.js или Python на вашей машине. Нужна для второй половины гайда — проверки токена.
- Современный браузер. Chrome, Firefox, Edge или Safari актуальной версии с открытыми инструментами разработчика.
- Мобильный прокси с возможностью смены IP. Понадобится в диагностическом разделе, чтобы посмотреть, как виджет реагирует на разные сети и ротацию адресов.
Системные требования
Turnstile не требовательный. Виджет работает в любом браузере, который поддерживает современный JavaScript, и загружает свой код с домена challenges.cloudflare.com. Если в вашей сети или в расширениях браузера этот домен заблокирован, виджет не загрузится — учитывайте это при тестировании. Для серверной проверки требуется возможность делать исходящие HTTPS-запросы.
Что подготовить перед началом
- Заведите текстовый файл для заметок. В него вы будете записывать site key, название виджета, список хостнеймов и результаты тестов.
- Откройте страницу с формой, которую хотите защитить, и сохраните её копию с пометкой даты. Это ваша резервная копия.
- Если у вас есть серверный обработчик формы, сделайте копию и его тоже. Мы будем добавлять в него код проверки.
- Проверьте, что ваш локальный или боевой сервер отдаёт страницу по HTTPS или через localhost. Turnstile работает и по обычному HTTP, но на боевом сайте вам всё равно нужен HTTPS.
⚠️ Внимание: Секретный ключ виджета нельзя хранить в HTML, в JavaScript на странице или в публичном репозитории. Он живёт только на сервере. Если вы случайно опубликовали его, сразу перевыпустите ключ в панели Cloudflare — старый перестанет работать.
Базовые понятия: как устроен Cloudflare Turnstile
Чтобы дальнейшие шаги были понятными, разберём ключевые термины простым языком.
Ключевые термины
- Виджет — тот блок, который видит посетитель. Технически это iframe, загруженный с домена Cloudflare и встроенный в вашу страницу.
- Site key — публичный идентификатор виджета. Он вставляется в HTML и виден всем. По нему Cloudflare понимает, какой виджет отрисовать и для каких доменов он разрешён.
- Secret key — приватный ключ. Им ваш сервер подтверждает, что пришедший токен настоящий. Никогда не покидает сервер.
- Токен — строка, которую виджет выдаёт после успешной проверки. Она кладётся в скрытое поле формы и уходит на ваш сервер вместе с остальными данными.
- Siteverify — эндпоинт Cloudflare, куда сервер отправляет токен вместе с секретным ключом и получает ответ: успех или нет.
- Режим виджета — способ показа: управляемый (Managed), неинтерактивный (Non-interactive) или невидимый (Invisible). Разница описана ниже.
- Хостнейм — домен, на котором разрешено использовать виджет. Если домен не указан, виджет откажется работать с ошибкой.
Принцип работы в четырёх фразах
- Страница загружает скрипт Turnstile, и виджет тихо запускает в браузере набор проверок.
- Cloudflare собирает результаты, оценивает их вместе с данными о сети и решает: пропустить сразу, показать галочку для подтверждения или отказать.
- При успехе виджет генерирует одноразовый токен и подставляет его в форму.
- Ваш сервер получает форму, отправляет токен на siteverify и только при положительном ответе обрабатывает заявку.
Что Turnstile проверяет — общая картина
Здесь важно понимать главное. Cloudflare Turnstile не смотрит на «человечность» через головоломки с картинками. Он оценивает согласованность окружения: насколько браузер, сеть и поведение сходятся в одну правдоподобную картину. Основные группы сигналов:
- Окружение браузера. Скрипт выполняет серию небольших JavaScript-задач и проверяет, что среда ведёт себя как настоящий браузер: как устроены объекты окна, как рендерится графика, есть ли признаки автоматизации, совпадает ли заявленный User-Agent с реальными возможностями движка.
- Доказательство работы. Виджет просит браузер выполнить небольшое вычисление. Для человека это доли секунды, для бота, который открывает тысячи страниц, — ощутимая нагрузка.
- Сетевые сигналы. Репутация IP-адреса и автономной системы, из которой идёт запрос, соответствие сетевых характеристик заявленному браузеру, история запросов с этого адреса по всей сети Cloudflare.
- Токены доверия устройства. На устройствах Apple и в некоторых других экосистемах Turnstile может запросить у операционной системы подтверждение, что перед ним настоящее устройство, — и тогда проверка проходит вообще без вычислений.
- Поведение на странице. Время появления виджета, момент отправки формы, естественность действий в управляемом режиме.
Что Turnstile не делает: не собирает данные для рекламного профилирования, не отслеживает пользователя между сайтами через сторонние cookie и никогда не показывает пазлы с картинками. Это важно и с точки зрения закона о персональных данных, и с точки зрения конверсии — посетители не уходят из-за раздражающей капчи.
Три режима виджета
- Managed — режим по умолчанию. Виджет виден, крутит индикатор, и если сомневается, показывает галочку, которую нужно нажать. Подходит для большинства форм.
- Non-interactive — виджет виден, но никогда не требует действий. Либо проходит сам, либо выдаёт ошибку. Хорош для страниц, где нельзя допустить лишних кликов.
- Invisible — виджет вообще не отрисовывается. Проверка идёт в фоне. Удобен для кнопок и форм, где вы не хотите менять дизайн, но требует аккуратной обработки ошибок.
Шаг 1: Разбираемся, что именно Turnstile видит с вашей стороны
Цель этапа: перед тем как что-то настраивать, вы должны понимать, какие данные о вашем окружении получает виджет. Это база для диагностики на следующих шагах и для осознанной работы через мобильные прокси.
Как посмотреть работу виджета своими глазами
- Откройте любой сайт, где стоит Cloudflare Turnstile. Такие виджеты легко узнать по логотипу Cloudflare в правом нижнем углу блока и ссылкам «Privacy» и «Terms».
- Нажмите F12 или правой кнопкой мыши — «Просмотреть код», чтобы открыть инструменты разработчика.
- Перейдите на вкладку «Network» (Сеть) и обновите страницу.
- В строке фильтра введите challenges.cloudflare.com. Вы увидите несколько запросов: загрузку api.js, загрузку самого iframe виджета и один или несколько POST-запросов — это и есть отправка результатов проверок.
- Откройте вкладку «Elements» (Элементы) и найдите блок с классом cf-turnstile. Внутри него после успешной проверки появится скрытое поле input с именем cf-turnstile-response и длинной строкой в значении. Это токен.
Совет: Содержимое POST-запросов зашифровано и обфусцировано, читать его бесполезно. Смотрите на другое: сколько запросов ушло, сколько времени заняла проверка и сменился ли статус виджета на «Success». Это и есть ваш внешний индикатор доверия.
Что Turnstile видит о вашем браузере
Виджет выполняет JavaScript прямо в вашем окне, поэтому ему доступно всё, что доступно любому скрипту на странице: версия движка, установленные API, размеры экрана, часовой пояс, языки интерфейса, особенности рендеринга графики и шрифтов, поведение функций, которые в автоматизированных браузерах часто переопределены. Он не читает ваши файлы и не лезет в другие вкладки. Но он отлично замечает, когда браузер заявляет одно, а делает другое. Например, User-Agent говорит «Chrome на Android», а в окружении нет сенсорных событий и есть API, которых на мобильных устройствах не бывает.
Что Turnstile видит о вашей сети
Здесь начинается самое интересное для тех, кто работает через мобильные прокси. Все запросы виджета идут на серверы Cloudflare, а значит, Cloudflare видит ваш внешний IP-адрес, его автономную систему (то есть оператора), страну, а также низкоуровневые характеристики соединения — как именно ваш клиент устанавливает защищённое соединение. Эти характеристики у разных браузеров разные, и Cloudflare сравнивает их с заявленным User-Agent.
Мобильные операторы выдают адреса из больших общих пулов, за одним адресом одновременно сидят сотни реальных абонентов. Поэтому такие адреса сами по себе имеют нейтральную или хорошую репутацию — заблокировать их означало бы заблокировать реальных людей. Но репутация — только один из сигналов. Если с мобильного адреса приходит браузер, у которого сетевой отпечаток настольного скрипта, часовой пояс другого континента и признаки автоматизации, картина перестаёт сходиться, и виджет переключается в интерактивный режим или отказывает.
Что Turnstile видит о вашем поведении
В управляемом режиме виджет обращает внимание на то, как быстро форма отправляется после загрузки, взаимодействовал ли пользователь со страницей, естественно ли выглядит клик по галочке. В невидимом и неинтерактивном режимах поведенческий компонент минимален — решение принимается по окружению и сети.
✅ Проверка: На этом этапе вы должны уметь открыть вкладку Network, отфильтровать запросы к challenges.cloudflare.com, увидеть скрытое поле cf-turnstile-response и объяснить своими словами три группы сигналов: браузер, сеть, поведение. Если это получилось — переходите к созданию своего виджета.
Возможные проблемы
- Запросов к challenges.cloudflare.com нет вообще. Скорее всего, домен блокируется расширением браузера или корпоративным фильтром. Отключите блокировщики на время тестов.
- Виджет висит в состоянии проверки бесконечно. Проверьте системное время на компьютере: сильное расхождение с реальным временем ломает проверку.
Шаг 2: Создаём виджет в панели Cloudflare
Цель этапа: получить пару ключей — site key и secret key — и правильно настроить список доменов и режим работы.
- Откройте панель управления Cloudflare и войдите в аккаунт. Если аккаунта нет — нажмите «Sign up», введите почту и пароль, подтвердите письмо.
- В левом меню найдите пункт Turnstile. Если у вас несколько аккаунтов, сначала выберите нужный на главной странице.
- Нажмите синюю кнопку Add widget (Добавить виджет).
- В поле Widget name введите понятное название, например «Лендинг заявки — основной». Название видно только вам, но при десятке виджетов оно спасёт от путаницы.
- В блоке Hostname management нажмите Add hostnames и введите домены, на которых будет работать виджет. Вводите без протокола и без пути: example.ru, а не https://example.ru/form. Поддомены нужно добавлять отдельно или указывать корневой домен — тогда поддомены тоже будут разрешены.
- Для локальных тестов добавьте в список localhost. Это официально поддерживается и не мешает боевой работе.
- В блоке Widget Mode выберите режим. Для первого раза берите Managed — так вы увидите все состояния виджета, включая интерактивное.
- Опцию Pre-clearance пока оставьте выключенной. Она нужна, только если сайт проксируется через Cloudflare, и о ней мы поговорим в продвинутом разделе.
- Нажмите Create.
- На следующем экране вы увидите два поля: Site Key и Secret Key. Скопируйте оба в файл заметок. Секретный ключ можно посмотреть позже в настройках виджета, но удобнее сохранить сразу.
Совет: Создайте сразу два виджета — один для боевого домена, второй с именем «Тест» и хостнеймом localhost. Так вы будете экспериментировать с режимами и настройками, не трогая статистику рабочего виджета.
Как выглядит правильный результат
В списке Turnstile появится карточка с названием виджета, его режимом и списком хостнеймов. Site key начинается с «0x» и имеет длину около 24 символов, secret key — тоже с «0x», но длиннее. Если ключ выглядит иначе, вы, скорее всего, скопировали не то поле.
✅ Проверка: В вашем файле заметок записаны site key, secret key, название виджета, список хостнеймов и выбранный режим. В панели Cloudflare виджет отображается в списке со статусом активного.
Возможные проблемы
- Кнопка Create неактивна. Не добавлен ни один хостнейм или введён с ошибкой (протокол, слэш, пробел).
- Не находится пункт Turnstile в меню. Вы находитесь внутри настроек конкретного домена. Вернитесь на уровень аккаунта — Turnstile живёт там, а не внутри зоны.
Шаг 3: Встраиваем виджет на страницу с формой
Цель этапа: виджет отображается на вашей странице, проходит проверку и подставляет токен в форму.
Подключаем скрипт
- Откройте HTML-файл страницы с формой в редакторе.
- Внутри тега head или перед закрывающим тегом body добавьте строку подключения скрипта:
<script src='https://challenges.cloudflare.com/turnstile/v0/api.js' async defer></script>Атрибуты async и defer позволяют странице не ждать загрузки скрипта. Виджет появится чуть позже, но пользователь не увидит задержки в загрузке контента.
Размещаем контейнер виджета
- Найдите форму, которую защищаете. Обычно это тег form с полями имени, почты, телефона.
- Прямо перед кнопкой отправки вставьте пустой блок с классом cf-turnstile и вашим site key:
<form action='/submit.php' method='POST'> <input type='text' name='name' placeholder='Ваше имя'> <input type='email' name='email' placeholder='Почта'> <div class='cf-turnstile' data-sitekey='ВАШ_SITE_KEY' data-theme='light'></div> <button type='submit'>Отправить</button> </form>- Замените ВАШ_SITE_KEY на ключ из файла заметок. Секретный ключ сюда вставлять нельзя.
- Сохраните файл и откройте страницу в браузере через localhost.
Что вы должны увидеть
Через одну-две секунды после загрузки в месте блока появится виджет размером примерно 300 на 65 пикселей. Сначала он показывает индикатор загрузки и текст «Verifying», затем — зелёную галочку и «Success». Если Cloudflare решил перепроверить окружение, появится чекбокс с текстом «Verify you are human» — нажмите его, и через мгновение виджет покажет успех.
Откройте инструменты разработчика, вкладку Elements, и разверните блок cf-turnstile. Внутри появилось скрытое поле input с именем cf-turnstile-response. Его значение — длинный токен. Именно он уйдёт на сервер при отправке формы.
Полезные атрибуты контейнера
- data-theme — light, dark или auto. Auto подстраивается под системную тему пользователя.
- data-size — normal, compact или flexible. Flexible растягивает виджет по ширине контейнера — удобно для мобильной вёрстки.
- data-language — код языка, например ru. По умолчанию виджет берёт язык браузера.
- data-action — короткая метка, например login или checkout. Она вернётся в ответе siteverify и поможет отличать формы в статистике.
- data-callback — имя JavaScript-функции, которая вызовется после успеха. В неё придёт токен.
- data-error-callback — функция, которая получит код ошибки, если что-то пошло не так.
- data-refresh-expired — что делать, когда токен устарел: auto перезапрашивает сам, manual показывает кнопку обновления, never ничего не делает.
Совет: Сразу добавьте data-error-callback и выводите код ошибки в консоль. Коды Turnstile информативны: серия 110xxx говорит о проблемах с ключом или доменом, 300xxx — о сбое выполнения в браузере, 600xxx — о том, что проверка не пройдена. Без этого вы будете гадать, почему виджет молчит.
Альтернативный путь: явный рендер через JavaScript
Если вы работаете во фреймворке или хотите контролировать момент появления виджета, замените неявный рендер на явный. Добавьте к адресу скрипта параметр render=explicit и вызовите turnstile.render с нужными параметрами:
turnstile.render('#my-widget', { sitekey: 'ВАШ_SITE_KEY', theme: 'auto', action: 'signup', callback: function(token) { console.log('Токен получен', token.length); } });Такой способ позволяет перерисовать виджет после ошибки методом turnstile.reset и получить текущий токен методом turnstile.getResponse.
✅ Проверка: Виджет отображается на странице, показывает «Success», в DOM присутствует поле cf-turnstile-response с токеном, в консоли нет ошибок. Попробуйте обновить страницу три-четыре раза — каждый раз должен появляться новый токен.
Возможные проблемы
- Виджет показывает ошибку 110200. Домен, с которого открыта страница, не добавлен в хостнеймы виджета. Проверьте, что открываете именно через localhost, а не через 127.0.0.1 или file:// — это разные хостнеймы.
- Виджет не появляется, в консоли пусто. Скрипт не загрузился. Проверьте адрес скрипта на опечатки и отсутствие блокировщиков.
- Виджет ломает вёрстку. Используйте data-size='flexible' или оберните блок в контейнер нужной ширины.
Шаг 4: Настраиваем серверную проверку токена
Цель этапа: сервер отклоняет любые отправки формы без действующего токена. Это самый важный шаг — без него виджет остаётся просто украшением, потому что бот может отправить POST-запрос напрямую, минуя страницу.
Как устроен запрос к siteverify
Ваш сервер отправляет POST-запрос по адресу https://challenges.cloudflare.com/turnstile/v0/siteverify с полями:
- secret — ваш секретный ключ;
- response — токен из поля cf-turnstile-response;
- remoteip — IP посетителя, необязательно, но полезно;
- idempotency_key — необязательный уникальный идентификатор запроса, о нём в продвинутом разделе.
В ответ приходит JSON. Ключевые поля:
{ "success": true, "challenge_ts": "2026-03-14T10:22:31.000Z", "hostname": "example.ru", "error-codes": [], "action": "signup", "cdata": "" }Токен живёт 300 секунд и является одноразовым. Повторная проверка того же токена вернёт ошибку timeout-or-duplicate.
Пример на PHP
- Откройте файл-обработчик формы, например submit.php.
- В самом начале, до любой работы с данными формы, добавьте блок проверки:
<?php $token = $_POST['cf-turnstile-response'] ?? ''; if ($token === '') { http_response_code(400); exit('Проверка не пройдена: нет токена'); } $data = [ 'secret' => getenv('TURNSTILE_SECRET'), 'response' => $token, 'remoteip' => $_SERVER['REMOTE_ADDR'] ]; $ch = curl_init('https://challenges.cloudflare.com/turnstile/v0/siteverify'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $raw = curl_exec($ch); curl_close($ch); $result = json_decode($raw, true); if (empty($result['success'])) { http_response_code(403); exit('Проверка не пройдена: ' . implode(',', $result['error-codes'] ?? ['no-response'])); }