Makina Blog

Le blog Makina-corpus

Un captcha de calcul simple


Ajouter un mécanisme de captcha en quelques lignes de javascript.

Le contexte

Un questionnaire utilisateur est la cible de robot spammeurs, et nous ne voulons pas utiliser un module de captcha pour gérer ce problème (soit parce qu'on n'a pas envie d'ajouter un nième module dans notre CMS, soit parce que les modules existants sont moches et globalement assez inefficaces).

La solution

Nous allons utiliser le principe assez classique de poser une question d'arithmétique écrite en français (par exemple "combien font cinq plus trois ?").

Pour cela nous allons ajouter un champ supplémentaire dans notre formulaire:

<label for="human" id="human-question"></label>
<input id="human-answer" type="text" />

Notons que le champ INPUT n'a pas de NAME, il ne sera donc pas soumis avec les autres valeurs du formulaire.

Ensuite nous allons générer une question en javascript:

var numbers = ["zero", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix"];
var num1 = Math.floor(Math.random() * 10);
var num2 = Math.floor(Math.random() * 10);
document.getElementById('human-question').innerHTML = "Combien font " + numbers[num1] + " plus " + numbers[num2] + " ?";

Et dans le submit du formulaire, on va tester le résultat saisie par l'utilisateur:

document.myform.onsubmit = function() {
 var sum = document.getElementById('human-answer').value;
 if(Number.parseInt(sum) != num1 + num2) {
 alert("Désolé, votre calcul est incorrect, cela laisse penser que vous êtes un robot.");
 return false;
 }
};

Par mesure de précaution contre les robots se contentant d'analyse le DOM, il peut être judicieux d'enlever l'attribut ACTION du formulaire, et de ne l'ajouter qu'en cas de calcul correct:

<form action="" method="POST" name="myform">
...

document.myform.onsubmit = function() {
 var sum = document.getElementById('human-answer').value;
 if(Number.parseInt(sum) != num1 + num2) {
 alert("Désolé, votre calcul est incorrect, cela laisse penser que vous êtes un robot.");
 return false;
 } else {
 document.myform.action = "./the_url";
 }
};

Conclusion

Clairement, c'est une solution très simple, elle n'est pas à l'épreuve des balles, en revanche elle est légère, facile à intégrer (aucune dépendance Javascript ou backend), et elle est raisonnablement accessible (certes, la question n'est pas présente dans le DOM au chargement, donc certains outils ne la traiteront pas, mais pour ceux qui interprètent le javascript, le résultat produit est une question en français, clairement plus simple à traiter qu'une image biscornue).

Actualités en lien

Image
Symfony + Vue.js
21/06/2022 - 15:02

Créer une application Symfony/Vue.js

Pour faire des essais ou bien démarrer un nouveau projet, vous avez besoin de créer rapidement une application Symfony couplée avec un front Vue.js ? Suivez le guide !

Voir l'article
Image
Logo Cypress
11/10/2021 - 16:38

Retour d’expérience : tests fonctionnels avec Cypress

Dans le cadre d'un de nos projets de développement spécifique, l’équipe Makina Corpus a été amenée à coder un important logiciel métier avec de nombreuses entités et règles de gestion : l’Hydroportail.

Voir l'article
29/03/2019 - 15:28

Des boucles de composants génériques avec Angular

Ou comment faire des composants de listes réutilisables avec n'importe quel objet.

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus