GuidePlateformes et outils

Turnstile ne s'arrête pas au widget : validez chaque envoi protégé côté serveur

Le navigateur crée un jeton ; le serveur doit le vérifier avant d'accepter l'action. Testez expiration, réutilisation et échec, pas seulement le succès affiché.

Un ticket unique franchit un contrôle étroit vers un bouclier, tandis que d'autres tickets attendent dehors.
Sur cette page

L'apparition d'un widget Turnstile sur un formulaire ne prouve pas sa protection. La documentation de validation côté serveur impose la vérification du jeton via Siteverify. Si l'application accepte l'envoi sans ce contrôle, une expérience apparemment réussie dans le navigateur n'a pas établi une décision fiable du serveur.

L'objectif est simple : aucune action protégée ne doit continuer uniquement parce que le navigateur annonce une réussite. Construisez et testez d'abord la décision serveur, puis reliez le widget et le parcours de reprise pour l'utilisateur. Ce guide décrit un flux à mettre en œuvre et vérifier, pas un test des applications des lecteurs effectué par ClickSyrup.

Suivez le jeton du navigateur au serveur

Le guide de démarrage distingue la sitekey publique de la clé secrète privée. La sitekey appartient à l'intégration cliente ; le secret sert à la vérification sur le serveur. Ne placez pas ce secret dans le code du navigateur, un dépôt public ou une configuration visible du client pour faire fonctionner rapidement un prototype.

Lorsque le navigateur transmet le jeton avec le formulaire, envoyez-le depuis le backend vers l'endpoint fixe Siteverify, avec le secret et le jeton comme paramètres obligatoires. Traitez la réponse comme des données à contrôler, pas comme une autorisation implicite parce que la requête HTTP s'est terminée. L'application doit obtenir le résultat avant d'exécuter l'action protégée.

Placez l'action métier après cette décision. Envoyer un e-mail, créer un enregistrement ou accepter une demande avant de vérifier le jeton inverse la protection. Décrivez explicitement cet ordre dans la tâche d'implémentation pour que les équipes frontend et backend ne supposent pas chacune que l'autre l'a imposé.

Prévoyez le traitement d'un jeton absent, refusé ou d'une réponse de vérification indisponible. N'acceptez pas silencieusement l'action dans ces cas. Offrez un chemin de nouvelle tentative utilisable et conservez les saisies non envoyées appropriées, sans mettre de données sensibles dans les journaux. Perdre un long message est un problème d'expérience à résoudre, pas une raison de sauter la validation.

Expiration et réutilisation exigent des tests distincts

Cloudflare documente une durée de vie de 300 secondes et une validation à usage unique. Un jeton expiré ou déjà validé peut produire timeout-or-duplicate. Un jeton obtenu à l'ouverture de la page peut donc être inutilisable lorsque le visiteur termine un long formulaire.

Testez cette saisie lente plutôt que le seul envoi immédiat après la réussite du widget. Confirmez que l'application obtient un nouveau jeton et permet de réessayer sans répéter involontairement l'action métier. Le visiteur ne doit pas comprendre la mécanique des jetons pour se remettre d'un délai ordinaire.

Séparez la réutilisation du jeton de l'idempotence de l'opération. Un jeton valide ne garantit pas, à lui seul, l'absence de deux enregistrements identiques après un nouvel essai réseau ou un double clic. Faites reconnaître à l'opération ses propres demandes répétées lorsque c'est nécessaire, puis testez ce comportement indépendamment du widget.

Si le backend répète un appel de vérification, utilisez les mécanismes de nouvelle tentative et d'idempotence documentés par l'API, sans supposer qu'un même jeton peut être validé indéfiniment. Notez la couche répétée : envoi navigateur, requête Siteverify ou transaction métier. Les confondre rend les pannes intermittentes difficiles à expliquer.

Vérifiez l'hôte et l'action attendus, pas seulement le succès

La réponse de vérification contient du contexte, notamment hostname et, lorsqu'il est configuré, action. Comparez ces champs aux valeurs attendues définies par l'application. N'acceptez pas un hôte ou une action attendus transmis par le même formulaire non fiable : la demande définirait alors elle-même la règle qu'elle doit respecter.

Le guide de gestion des noms d'hôte explique l'autorisation des domaines du widget. Il précise qu'ajouter un domaine racine autorise ses sous-domaines. Choisissez cette portée volontairement et réexaminez-la lors du passage de la préproduction à la production. La configuration du widget et le contrôle serveur doivent servir le déploiement prévu, pas autoriser accidentellement d'autres environnements.

Turnstile reste une couche. L'authentification identifie l'utilisateur, l'autorisation détermine ses droits, et l'application a encore besoin de validation des entrées et de contrôles de requêtes adaptés. Une épreuve réussie ne justifie pas d'accepter n'importe quelle donnée ni de laisser un utilisateur agir sur le compte d'une autre personne.

Examinez aussi la diffusion de la page. En présence de cache, gardez les réponses propres aux comptes et les états sensibles hors des caches partagés, selon notre guide du cache Cloudflare. Une épreuve qui fonctionne ne corrige pas une règle indépendante exposant du contenu privé.

Démontrez les cas négatifs avant la mise en ligne

Cloudflare fournit des clés de test et conseils d'implémentation pour contrôler les cas de réussite et d'échec. Utilisez ces identifiants documentés dans l'environnement de test approprié, pas comme protection en production. Ils permettent des tests répétables sans dépendre du résultat d'une véritable épreuve de visiteur.

Créez un relevé de recette couvrant un envoi valide, un jeton absent, une vérification échouée, un jeton expiré, la réutilisation d'un jeton validé et un hôte ou une action inattendus. Pour chaque cas, notez la réponse visible et l'exécution réelle, ou non, de l'opération par le backend. Un message rassurant ne prouve pas que rien n'a été accepté.

Ajoutez une interruption du service de vérification au plan et convenez du comportement visible avant le lancement. Vérifiez aussi la reprise lorsque le service redevient disponible. Intégrez ces contrôles à la routine de maintenance du site, surtout après des changements de formulaires, de reverse proxies, de secrets ou d'environnement de déploiement.

Le critère de lancement n'est pas une capture du widget. C'est un résultat reproductible : les demandes autorisées s'exécutent une fois comme prévu, les demandes refusées ne déclenchent pas l'action, les secrets restent sur le serveur et les visiteurs légitimes disposent d'une reprise claire. Voilà la différence entre un composant visible et une protection effectivement appliquée.

Traduit de l’édition source en anglais.

Plateformes abordéesCloudflare

Sources primaires