Aller au contenu

Cloudflare Turnstile

Cloudflare Turnstile est une alternative au CAPTCHA respectueuse de la vie privée, qui vérifie généralement les visiteurs sans aucun casse-tête. Frontmail l’utilise pour empêcher les bots d’abuser de votre clé publique.

Lorsqu’un modèle a Exiger un CAPTCHA (Turnstile) activé, chaque requête avec clé publique vers ce modèle doit contenir un jeton Turnstile valide ; sinon, elle échoue avec captcha_required ou captcha_failed avant de vous coûter un crédit. Les requêtes avec clé privée (depuis votre serveur) n’ont jamais besoin de CAPTCHA.

Où s’exécute le formulaire Clés Turnstile de qui Ce que vous faites
Votre site web Les vôtres – un widget gratuit dans votre propre compte Cloudflare Créez le widget, collez les deux clés dans Sécurité → Protection contre les bots (Turnstile), placez la clé de site dans votre formulaire.
Application mobile (@frontmail/react-native) La clé mobile partagée de Frontmail Rien – <TurnstileWebView> charge la clé lui-même.

Le forfait gratuit de Turnstile autorise 10 noms d’hôte par widget et 20 widgets par compte ; un widget valable sur n’importe quel nom d’hôte n’existe que dans le forfait Enterprise de Cloudflare. Une clé Frontmail unique ne peut donc pas couvrir les sites de tous nos clients. Votre propre widget est gratuit, se configure en deux minutes environ et ne fonctionne que sur les noms d’hôte que vous indiquez – personne ne peut donc réutiliser votre CAPTCHA sur un autre site.

  1. Connectez-vous au tableau de bord Cloudflare (un compte gratuit suffit – votre domaine n’a pas besoin d’utiliser Cloudflare).
  2. Ouvrez Turnstile et cliquez sur Add widget.
  3. Donnez-lui un nom, p. ex. Formulaire de contact.
  4. Ajoutez tous les noms d’hôte sur lesquels votre formulaire s’exécute, p. ex. example.com et www.example.com. N’ajoutez localhost que si vous voulez tester en local avec de vraies clés – pour le développement local, vous pouvez utiliser les clés de test.
  5. Widget mode : Managed convient (Cloudflare n’affiche une case à cocher que lorsqu’il a un doute).
  6. Cliquez sur Create et copiez la Site Key et la Secret Key.
  1. Dans le tableau de bord Frontmail, ouvrez Sécurité et trouvez la carte Protection contre les bots (Turnstile).
  2. Collez la clé de site et la clé secrète, puis cliquez sur Enregistrer les clés.
  3. Frontmail vérifie immédiatement la clé secrète auprès de Cloudflare – une clé secrète erronée est refusée avec un message clair. La clé secrète est stockée chiffrée et n’est plus jamais affichée. Vous pouvez changer les clés à tout moment avec Remplacer les clés ou les supprimer avec Supprimer les clés.
  4. Après l’enregistrement, cliquez sur Activer le CAPTCHA pour tous les modèles pour activer le CAPTCHA sur tous les modèles existants en une seule fois. Les modèles utilisés comme réponse automatique sont ignorés – ils sont envoyés par Frontmail, pas par votre formulaire.

Désormais, les nouveaux modèles ont le CAPTCHA activé par défaut. Les modèles créés avant l’ajout des clés démarrent avec le CAPTCHA désactivé – utilisez le bouton ci-dessus ou activez-le modèle par modèle dans l’éditeur de modèles, sous Paramètres → Protection.

Sans clés, l’éditeur de modèles ne vous laisse pas activer le CAPTCHA et vous renvoie vers la page Sécurité. L’exception est Autoriser les applications mobiles : vous pouvez alors l’activer (avec un avertissement), car les applications mobiles utilisent la clé partagée de Frontmail – les requêtes depuis des sites web vers ce modèle échouent avec captcha_not_configured jusqu’à ce que vous ajoutiez vos clés.

Utilisez votre clé de site (elle est publique – la clé secrète ne quitte jamais Frontmail). L’onglet Extraits de code de l’éditeur de modèles contient déjà le widget avec votre clé de site lorsque le modèle exige le CAPTCHA.

Avec du HTML simple et sendForm – affichez le widget à l’intérieur du formulaire. Turnstile ajoute un champ caché cf-turnstile-response, que sendForm envoie automatiquement :

<form id="contact">
<!-- vos champs -->
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY"></div>
<button>Envoyer</button>
</form>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

Avec les composants pour frameworks – passez votre clé de site à FrontmailForm : il charge Turnstile, affiche le widget, envoie le jeton et réinitialise le widget pour vous :

  • React et Svelte : <FrontmailForm turnstileSiteKey="YOUR_TURNSTILE_SITE_KEY" …>
  • Vue : <FrontmailForm turnstile-site-key="YOUR_TURNSTILE_SITE_KEY" …>

Avec send() – affichez vous-même le widget et passez le jeton dans les options :

await send('svc_01J9…', 'tpl_contact', params, { turnstileToken: token });

Via l’API REST, passez turnstile_token dans le corps JSON, ou cf-turnstile-response dans les formulaires multipart.

Les requêtes provenant d’un site web portent un en-tête Origin (ou Referer). Frontmail vérifie leur jeton avec votre clé secrète et contrôle aussi que Cloudflare a résolu le widget sur le même nom d’hôte que celui d’où vient la requête. Un jeton émis sur un autre nom d’hôte échoue avec captcha_failed (details.reason: "hostname_mismatch") – indiquez donc tous les noms d’hôte de votre site dans le widget.

@frontmail/react-native n’a besoin d’aucune clé de site. Son <TurnstileWebView> récupère la clé de site mobile de Frontmail depuis GET /v1/public-config (mise en cache) et affiche le widget dans une page intégrée à l’URL https://mobile.frontmail.dev. Les requêtes natives n’ont pas d’en-tête Origin. Activez Autoriser les applications mobiles – sans cette option, ces requêtes sont refusées avant la vérification CAPTCHA (même si aucun site autorisé n’est défini). Ce n’est qu’alors que Frontmail les vérifie avec sa clé secrète mobile partagée ; le CAPTCHA d’une organisation qui n’a pas autorisé les applications mobiles n’est jamais vérifié avec le widget partagé, accessible publiquement.

Vous pouvez aussi utiliser votre propre widget dans l’application : passez à <TurnstileWebView> une siteKey et une baseUrl dont le nom d’hôte figure dans votre widget (p. ex. https://example.com). Le SDK marque alors automatiquement la requête avec turnstile_key: "org" et Frontmail la vérifie avec votre clé secrète.

Les autres clients natifs (Flutter, Swift, Kotlin…) qui appellent directement l’API REST peuvent faire de même : affichez votre widget dans une WebView et envoyez turnstile_key: "org" avec turnstile_token.

Cloudflare publie des clés de test qui fonctionnent hors ligne, sur n’importe quel nom d’hôte :

Clé Valeur Résultat
Clé de site 1x00000000000000000000AA Réussit toujours
Clé secrète 1x0000000000000000000000000000000AA Réussit toujours
Clé secrète 2x0000000000000000000000000000000AA Échoue toujours

Frontmail les accepte dans Sécurité → Protection contre les bots (Turnstile) dans les environnements de développement.

Dans les tests automatisés, vous pouvez aussi envoyer avec une clé privée – les requêtes avec clé privée ne sont pas soumises à la vérification.

  • Un jeton est valable environ 5 minutes et ne peut être utilisé qu’une fois.
  • Après chaque envoi (réussi ou non), réinitialisez le widget (turnstile.reset()) avant la tentative suivante. Les composants pour frameworks le font automatiquement.
  • Les nouvelles tentatives du SDK pour un même envoi logique réutilisent la même clé d’idempotence. Une requête relancée qui avait déjà été acceptée reçoit la réponse de la première tentative avant la vérification Turnstile : un jeton déjà utilisé ne fait donc pas échouer la nouvelle tentative.
Code Statut Quand Solution
captcha_required 403 Le modèle exige le CAPTCHA et la requête n’a pas de jeton. Ajoutez le widget au formulaire, ou passez turnstileToken.
captcha_failed 403 Cloudflare a refusé le jeton – invalide, expiré, déjà utilisé, ou résolu sur un autre nom d’hôte (hostname_mismatch). Réinitialisez le widget et réessayez ; ajoutez tous vos noms d’hôte au widget.
captcha_not_configured 403 Requête d’un site web vers un modèle avec CAPTCHA activé, mais votre organisation n’a pas de clés Turnstile (ou, en production, uniquement des clés de test Cloudflare). Ajoutez les clés d’un vrai widget dans Sécurité → Protection contre les bots (Turnstile).

Vous pouvez désactiver Exiger un CAPTCHA (Turnstile) modèle par modèle dans l’éditeur de modèles, sous Paramètres → Protection – par exemple pour les modèles envoyés uniquement depuis votre serveur. Pour les formulaires publics, nous vous recommandons vivement de le laisser activé.