Écrit par Nuna C.
Les spams, publicités et autres joyeusetés sont monnaies courantes sur nos téléphones, boites mails et comptes de réseaux sociaux. Si de plus, vous proposez un formulaire d’inscription ou de contact sur votre site, l’occasion sera trop belle pour ces petits cabotins car vous leur offrez là un moyen supplémentaire de vous harceler.
Pour ceux qui veulent se prémunir de ce type de désagrément arrivant par ledit formulaire, une des solutions est de mettre en place un captcha. Un captcha est un petit exercice, un challenge que l’utilisateur va devoir valider pour voir sa requête accordée. L’idée étant de permettre aux humains d’utiliser le formulaire, mais d’empêcher que des robots puissent le soumettre, car ils ne devraient pas être capables de valider le challenge correctement.
Je vais donc vous proposer une implémentation de reCaptcha (le captcha de Google) dans une application Ruby.
Préparatifs
Pour commencer, nous avons le choix entre deux types de captcha, un visible qui demandera à l’utilisateur de cliquer sur la checkbox du captcha pour lancer le challenge, et un invisible (que l’on peut par exemple attacher à un bouton) qui lancera le challenge sur l’action voulue.
Une fois choisi, il faut créer ou avoir un compte Google, s’y connecter, puis renseigner les informations du domaine sur lequel le captcha va être appliqué. Sélectionnez le type de captcha que vous voulez, donnez-lui un libellé et renseignez le(s) domaine(s). En développement, vous pouvez utiliser localhost
ou l’IP sur laquelle vous visionnez l’application. Une fois enregistré, vous allez avoir une clé et un jeton secret pour le captcha de ce(s) domaine(s).
Le front
Une des possibilités de mise en place de reCaptcha sur un formulaire est d’intégrer le script de reCaptcha sur la page et d’ajouter la balise ou les attributs nécessaires au HTML :
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
Avec les attributs async
et defer
de la balise script
, le script du captcha sera appelé de manière asynchrone et attendra que la page soit complètement chargée, pour se charger à son tour.
Pour reCaptcha V2, il faut ajouter cette balise dans le formulaire :
<div class="g-recaptcha" data-sitekey="la_clé_du_site"></div>
Pour un captcha invisible, il faut ajouter ces attributs sur l’élément déclencheur du challenge :<button class=”g-recaptcha” data-sitekey=”la_clé_du_site” data-callback=’onReCaptchaValid’>Envoyer</button>
Le reCaptcha invisible demandera un bout de JavaScript supplémentaire pour être invoqué (l’appel du callback) :
<script type="text/javascript"> function onReCaptchaValid(token) { document.getElementById('id_du_formulaire').submit(); } </script>
Arrivé ici, le logo de reCaptcha devrait apparaître sur la page du formulaire :
Un clic sur la checkbox du captcha :
ou la soumission du formulaire (en fonction du type de captcha que vous avez choisi), devrait invoquer le challenge :
L’utilisateur à le choix entre un challenge visuel ou un audio. En cliquant sur l’icône du casque, un challenge audio prendra la place de l’image ci-dessus.
Il est préférable de placer les balises script
dans le head
de la page (ce qui est d’ailleurs conseillé dans la documentation), car en les plaçant ailleurs, vous prenez le risque que le formulaire puisse être soumis avant que la librairie reCaptcha soit pleinement chargée. Le but étant de se prémunir des robots et ceux-ci étant très rapides, nul doute que c’est ce qui se produirait à chaque fois.
Des options de configuration sont disponibles à l’appel du script, mais aussi apposables sur la balise porteuse du captcha. On peut ainsi influer sur le thème, la taille, ou bien choisir un captcha audio.
Enfin pour des utilisations plus avancées, il est possible de manipuler le captcha avec une API JavaScript.
La partie back
Maintenant que l’utilisateur peut challenger ce captcha, il faut tout de même vérifier s’il remporte la manche ou non. C’est là que la partie back entre en jeu.
Lorsque l’utilisateur valide son challenge, le formulaire est envoyé avec un attribut supplémentaire : g-recaptcha-response
. Ce paramètre contient un jeton contenant lui-même la réponse de l’utilisateur. Il va donc falloir l’envoyer au service de Google pour vérification.
Voici une implémentation :
require 'uri' require 'net/http' require 'json' defrecaptcha_valid?(code) returnfalseif code.to_s.empty? uri = URI('https://www.google.com/recaptcha/api/siteverify') args = { secret: le_secret_du_site, response: code } begin res = Net::HTTP.post_form(uri, args) status = JSON.parse(res.body) rescuereturntrueend status['success']end
On est sympa ici, dans le cas ou nous n’arrivons pas à joindre le serveur de Google, le bénéfice du doute est laissé à l’utilisateur.
La variable status
va contenir plusieurs informations, dont le résultat du contrôle contenu dans la clé success
. C’est ce résultat qui est retourné par la méthode ici.
L’implémentation est en Ruby, mais transposable dans n’importe quel autre langage. D’ailleurs, la documentation donne aussi d’autres options pour gérer cette vérification avec JavaScript.
Conclusion
reCaptcha est vraiment simple à mettre en place, il permettra d’être plus serein quant aux informations de contact reçues par le formulaire et ainsi éviter d’être la cible de spams par son biais. Alors pourquoi s’en priver !