En este artículo hemos intentado responder a todas las preguntas clave. Para empezar a resolver la tarea, primero hay que determinar qué sistema de protección se está utilizando. Para ello, puedes consultar la lista de captchas y sistemas de protección antibot más populares, donde se muestran ejemplos visuales y señales clave que te ayudarán a identificar rápidamente con qué estás tratando.
Si descubres que tu sitio web utiliza Cloudflare Turnstile, el siguiente paso será analizar con más detalle sus propiedades y su funcionamiento. En este mismo artículo también puedes consultar la guía de integración de Cloudflare Turnstile para comprender por completo cómo funciona en tu sitio. Esto te permitirá no solo entender la protección actual, sino también planificar correctamente su mantenimiento.
Al probar formularios que incluyen Cloudflare Turnstile, normalmente debes verificar que la captcha funcione y esté integrada correctamente.
Puedes comprobar manualmente la captcha incrustada en tu sitio.
Para la resolución automática puedes usar herramientas como CapMonster Cloud, que reciben los parámetros de la captcha, los procesan en sus servidores y devuelven un token listo para usar. Inserta ese token en el formulario para pasar la verificación sin interacción del usuario.
Trabajar con CapMonster Cloud mediante la API suele implicar los siguientes pasos:
En la solicitud para resolver Cloudflare Turnstile es necesario especificar los siguientes parámetros:
type - TurnstileTask;
websiteURL - dirección de la página donde se resuelve el CAPTCHA;
websiteKey - clave de Turnstile.
https://api.capmonster.cloud/createTask{
"clientKey": "API_KEY",
"task": {
"type": "TurnstileTask",
"websiteURL": "http://tsmanaged.zlsupport.com",
"websiteKey": "0x4AAAAAAABUYP0XeMJF0xoy"
}
}{
"errorId":0,
"taskId":407533072
}https://api.capmonster.cloud/getTaskResult{
"clientKey":"API_KEY",
"taskId": 407533072
}{
"errorId": 0,
"status": "ready",
"solution": {
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
"token": "0.iGX3xsyFCkbGePM3jP4P4khLo6TrLukt8ZzBvwuQOvbC...f61f3082"
}
}// npm install playwright @zennolab_com/capmonstercloud-client
import { chromium } from "playwright";
import { CapMonsterCloudClientFactory, ClientOptions, TurnstileRequest } from "@zennolab_com/capmonstercloud-client";
async function main() {
// 1. Resolver Turnstile a través de CapMonster Cloud
const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: 'YOUR_CAPMONSTER_API_KEY' })
);
const turnstileRequest = new TurnstileRequest({
websiteURL: 'http://tsmanaged.zlsupport.com',
websiteKey: '0x4AAAAAAABUYP0XeMJF0xoy',
});
const result = await cmcClient.Solve(turnstileRequest);
const token = result.solution.token;
console.log('Token de Turnstile recibido:', token);
// 2. Iniciar Playwright
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('http://tsmanaged.zlsupport.com');
// 3. Llenar login y contraseña
await page.fill('#username', 'your_username');
await page.fill('#password', 'your_password');
// 4. Esperar la aparición del campo de token oculto
await page.waitForSelector('#token', { state: 'attached', timeout: 60000 });
// 5. Insertar token y hacer visible el campo
await page.evaluate((t) => {
const tokenInput = document.querySelector('#token');
if (tokenInput) {
tokenInput.type = 'text'; // hacer visible el campo
tokenInput.value = t; // insertar token
console.log('Token insertado en el campo token');
} else {
console.error('Campo #token no encontrado');
}
}, token);
// 6. Verificar que el token se insertó realmente
const checkValue = await page.$eval('#token', el => el.value);
console.log('Verificación del valor del token:', checkValue);
// 7. Enviar formulario
await page.click('button[type="submit"]');
console.log('Formulario enviado con token de Turnstile');
// await browser.close();
}
main().catch(err => console.error(err));1. Vaya a la página de Cloudflare Turnstile, haga clic en Comenzar ahora.
2. Regístrese en el servicio.
3. En Turnstile Widgets, haga clic en el botón azul Add Widget.

4. Configure Cloudflare Turnstile, especifique:
5. Después de crear el widget, recibirá dos claves: Site Key y Secret Key.

6. Conectar la parte del cliente
1) Conectar el script de Turnstile
Renderizado automático (el widget se crea automáticamente cuando se carga la página):
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>Control programático (usted mismo crea el widget a través de JavaScript):
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit" defer></script>Importante: el script debe cargarse desde la URL exacta. El proxy o caché pueden causar fallos.
2) Crear un contenedor para el widget
Automático:
<div class="cf-turnstile" data-sitekey="<YOUR_SITEKEY>"></div>Programáticamente:
<div id="turnstile-container"></div>3) Configuración del widget
A través de atributos data:
<div class="cf-turnstile"
data-sitekey="<YOUR_SITEKEY>"
data-theme="light"
data-size="normal"
data-callback="onSuccess">
</div>A través de JavaScript:
const widgetId = turnstile.render("#turnstile-container", {
sitekey: "<YOUR_SITEKEY>",
theme: "light",
size: "normal",
callback: token => console.log("Token:", token)
});4) Trabajar con tokens
const token = turnstile.getResponse(widgetId); // obtener token
const isExpired = turnstile.isExpired(widgetId); // verificar caducidad
turnstile.reset(widgetId); // restablecer
turnstile.remove(widgetId); // eliminar
turnstile.execute("#turnstile-container"); // ejecución manual
5) Integración con formulario
<form id="my-form" method="POST">
<input type="hidden" name="cf-turnstile-response" id="cf-turnstile-response">
<button type="submit">Enviar</button>
</form>
<script>
function onSuccess(token) {
document.getElementById("cf-turnstile-response").value = token;
}
</script>
<title>Turnstile Example</title>
<!-- Conectar script de Turnstile -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>
<h1>Ejemplo de formulario con Turnstile</h1>
<form id="my-form">
<label for="username">Nombre:</label>
<input type="text" name="username" id="username" required>
<!-- Contenedor para Turnstile -->
<div class="cf-turnstile" data-sitekey="<YOUR_SITEKEY>" data-callback="onTurnstileSuccess"></div>
<button type="submit">Enviar</button>
</form>
<script>
// Callback que se llama después de pasar el CAPTCHA
function onTurnstileSuccess(token) {
console.log("Token de Turnstile recibido:", token);
// Guardar token en campo oculto del formulario (opcional)
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);
}
// Envío del formulario
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("¡Formulario enviado correctamente y token verificado!");
} else {
alert("Error de verificación del token de Turnstile. Inténtelo de nuevo.");
// Restablecer widget para que el usuario pueda completar el CAPTCHA nuevamente
turnstile.reset();
}
});
</script>
</body>
</html>
6) Configurar la parte del servidor
Proceso de verificación del servidor:
API de Siteverify:
https://challenges.cloudflare.com/turnstile/v0/siteverifyParámetros de solicitud:
Propiedades del token:
<?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);
}
// Uso
$secret_key = 'YOUR_SECRET_KEY';
$token = $_POST['cf-turnstile-response'] ?? '';
$remoteip = $_SERVER['REMOTE_ADDR'];
$result = validateTurnstile($token, $secret_key, $remoteip);
if($result['success']){
echo "¡Formulario enviado correctamente!";
} else {
echo "Error de verificación: " . implode(', ', $result['error-codes']);
}
?>
Si has heredado un sitio web que ya tiene un captcha u otro sistema de protección instalado y no tienes acceso al código, no pasa nada. Identificar qué tecnología se está utilizando es bastante sencillo. Para comprobar que todo funciona correctamente, puedes usar el servicio de reconocimiento CapMonster Cloud en un entorno de pruebas aislado, para asegurarte de que el mecanismo de procesamiento de tokens y la lógica de verificación funcionan correctamente.
En el caso de Cloudflare Turnstile, basta con detectar el sistema, analizar su comportamiento y confirmar que la protección funciona correctamente. En el artículo hemos mostrado cómo identificar Cloudflare Turnstile y dónde encontrar las instrucciones para su integración o reconfiguración, de modo que puedas mantener la protección con confianza y controlar su funcionamiento.