Cloudflare Turnstile
Cloudflare Turnstile es una alternativa a la CAPTCHA respetuosa con la privacidad que normalmente verifica a los visitantes sin ningún rompecabezas. Frontmail la usa para impedir que los bots abusen de tu clave pública.
Cuando una plantilla tiene activado Exigir CAPTCHA (Turnstile), cada solicitud con clave pública
para ella debe incluir un token de Turnstile válido; de lo contrario falla con
captcha_required o
captcha_failed antes de costarte un crédito. Las
solicitudes con clave privada (desde tu servidor) nunca necesitan CAPTCHA.
Cómo funciona
Sección titulada «Cómo funciona»| Dónde se ejecuta el formulario | Claves de Turnstile de quién | Qué tienes que hacer |
|---|---|---|
| Tu sitio web | Tuyas: un widget gratuito en tu propia cuenta de Cloudflare | Crea el widget, pega las dos claves en Seguridad → Protección contra bots (Turnstile) y pon la site key en tu formulario. |
App móvil (@frontmail/react-native) |
La clave móvil compartida de Frontmail | Nada: <TurnstileWebView> carga la clave por sí mismo. |
Por qué claves propias para los sitios web
Sección titulada «Por qué claves propias para los sitios web»El plan gratuito de Turnstile permite 10 nombres de host por widget y 20 widgets por cuenta; un widget que funcione en cualquier nombre de host solo está disponible en el plan Enterprise de Cloudflare. Por eso una única clave de Frontmail no puede cubrir los sitios web de todos nuestros clientes. Tu propio widget es gratuito, se configura en unos dos minutos y solo funciona en los nombres de host que indiques, así que nadie puede reutilizar tu CAPTCHA en otro sitio.
1. Crea un widget de Turnstile en Cloudflare
Sección titulada «1. Crea un widget de Turnstile en Cloudflare»- Inicia sesión en el panel de Cloudflare (basta con una cuenta gratuita; tu dominio no tiene por qué usar Cloudflare).
- Abre Turnstile y haz clic en Add widget.
- Ponle un nombre, p. ej. Formulario de contacto.
- Añade todos los nombres de host en los que funciona tu formulario, p. ej.
example.comywww.example.com. Añadelocalhostsolo si quieres probar con claves reales en local; para el desarrollo local puedes usar las claves de prueba. - Widget mode: Managed está bien (Cloudflare solo muestra una casilla cuando no está seguro).
- Haz clic en Create y copia la Site Key y la Secret Key.
2. Añade las claves a Frontmail
Sección titulada «2. Añade las claves a Frontmail»- En el panel de Frontmail, abre Seguridad y busca la tarjeta Protección contra bots (Turnstile).
- Pega la site key y la secret key y haz clic en Guardar claves.
- Frontmail comprueba el secreto con Cloudflare en el acto: un secreto incorrecto se rechaza con un mensaje claro. El secreto se guarda cifrado y no se vuelve a mostrar. Puedes cambiar las claves en cualquier momento con Sustituir claves o eliminarlas con Quitar claves.
- Después de guardar, haz clic en Activar la CAPTCHA en todas las plantillas para activarla de una vez en todas las plantillas existentes. Las plantillas que se usan como respuesta automática se omiten: las envía Frontmail, no tu formulario.
A partir de ese momento, las plantillas nuevas tienen la CAPTCHA activada por defecto. Las plantillas creadas antes de añadir las claves empiezan con la CAPTCHA desactivada: usa el botón anterior o actívala en cada plantilla desde el editor, en Ajustes → Protección.
Sin claves, el editor de plantillas no te deja activar la CAPTCHA y te remite a la página
Seguridad. La excepción es Permitir apps móviles: en ese caso sí puedes activarla (con una
advertencia), porque las apps móviles usan la clave compartida de Frontmail; las solicitudes desde
sitios web a esa plantilla fallarán con
captcha_not_configured hasta que añadas tus claves.
3. Añade el widget a tu formulario
Sección titulada «3. Añade el widget a tu formulario»Usa tu site key (es pública; la secret key nunca sale de Frontmail). La pestaña Fragmentos del editor de plantillas ya incluye el widget con tu site key cuando la plantilla exige la CAPTCHA.
Con HTML puro y sendForm: renderiza el widget dentro del formulario. Turnstile añade un campo
oculto cf-turnstile-response, que sendForm envía automáticamente:
<form id="contact"> <!-- tus campos --> <div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY"></div> <button>Enviar</button></form>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>Con los componentes para frameworks: pasa tu site key a FrontmailForm y él se encarga de
cargar Turnstile, renderizar el widget, enviar el token y restablecer el widget:
- React y Svelte:
<FrontmailForm turnstileSiteKey="YOUR_TURNSTILE_SITE_KEY" …> - Vue:
<FrontmailForm turnstile-site-key="YOUR_TURNSTILE_SITE_KEY" …>
Con send(): renderiza tú el widget y pasa el token en las opciones:
await send('svc_01J9…', 'tpl_contact', params, { turnstileToken: token });Con la API REST, pasa turnstile_token en el cuerpo JSON, o cf-turnstile-response en los
formularios multipart.
Cómo verifica Frontmail el token
Sección titulada «Cómo verifica Frontmail el token»Las solicitudes desde un sitio web llevan una cabecera Origin (o Referer). Frontmail verifica su
token con tu secret key y comprueba además que Cloudflare resolvió el widget en el mismo nombre
de host del que procede la solicitud. Un token de otro nombre de host falla con captcha_failed
(details.reason: "hostname_mismatch"), así que incluye en el widget todos los nombres de host de
tu sitio.
Apps móviles
Sección titulada «Apps móviles»@frontmail/react-native no necesita site key. Su
<TurnstileWebView> obtiene la site key móvil de Frontmail de
GET /v1/public-config (en caché) y muestra el widget
como una página incrustada con la URL https://mobile.frontmail.dev. Las solicitudes nativas no
llevan cabecera Origin. Activa Permitir apps móviles:
sin esa opción, esas solicitudes se rechazan antes de la comprobación de la CAPTCHA (también si no
hay sitios web permitidos configurados). Solo entonces Frontmail las verifica con su secreto móvil
compartido; en una organización que no ha permitido las apps móviles, la CAPTCHA nunca se comprueba
contra el widget compartido y públicamente disponible.
Tu propia clave en la app
Sección titulada «Tu propia clave en la app»También puedes usar tu propio widget en la app: pasa a <TurnstileWebView> siteKey y una
baseUrl cuyo nombre de host figure en tu widget (p. ej. https://example.com). El SDK marca
entonces la solicitud con turnstile_key: "org" automáticamente y Frontmail la verifica con tu
secreto.
Otros clientes nativos (Flutter, Swift, Kotlin…) que llamen directamente a la
API REST pueden hacer lo mismo: renderiza tu widget en un WebView y
envía turnstile_key: "org" junto con turnstile_token.
Desarrollo local
Sección titulada «Desarrollo local»Cloudflare publica claves de prueba que funcionan sin conexión y en cualquier nombre de host:
| Clave | Valor | Resultado |
|---|---|---|
| Site key | 1x00000000000000000000AA |
Siempre se supera |
| Secret key | 1x0000000000000000000000000000000AA |
Siempre se supera |
| Secret key | 2x0000000000000000000000000000000AA |
Siempre falla |
Frontmail las acepta en Seguridad → Protección contra bots (Turnstile) en los entornos de desarrollo.
En las pruebas automatizadas también puedes enviar con una clave privada: las solicitudes con clave privada se saltan la comprobación.
- Un token es válido durante unos 5 minutos y se puede usar una sola vez.
- Después de cada envío (con éxito o no), restablece el widget (
turnstile.reset()) antes del siguiente intento. Los componentes para frameworks lo hacen automáticamente. - Los reintentos del SDK de un mismo envío lógico reutilizan la misma clave de idempotencia. Un reintento de una solicitud que ya se había aceptado se responde con el resultado del primer intento antes de la comprobación de Turnstile, así que un token ya usado no hace fallar el reintento.
Errores
Sección titulada «Errores»| Código | Estado | Cuándo | Solución |
|---|---|---|---|
captcha_required |
403 | La plantilla exige la CAPTCHA y la solicitud no lleva token. | Añade el widget al formulario o pasa turnstileToken. |
captcha_failed |
403 | Cloudflare ha rechazado el token: no es válido, ha caducado, ya se usó o se resolvió en otro nombre de host (hostname_mismatch). |
Restablece el widget y vuelve a intentarlo; añade todos tus nombres de host al widget. |
captcha_not_configured |
403 | Una solicitud desde un sitio web a una plantilla con la CAPTCHA activada, pero tu organización no tiene claves de Turnstile (o, en producción, solo las claves de prueba de Cloudflare). | Añade las claves de un widget real en Seguridad → Protección contra bots (Turnstile). |
Desactivarla
Sección titulada «Desactivarla»Puedes desactivar Exigir CAPTCHA (Turnstile) en cada plantilla desde el editor, en Ajustes → Protección; por ejemplo, en plantillas que solo se envían desde tu servidor. En los formularios públicos te recomendamos encarecidamente mantenerla activada.