Créer un captcha personnalisé

Voir la vidéo

Dans ce tutoriel je vous propose de découvrir comment créer un système de captcha personnalisé en PHP & JavaScript. L'objectif est de créer un mini-puzzle sur lequel l'utilisateur devra placer une pièce au bon endroit pour confirmer qu'il n'est pas un robot.

Sommaire

00:00 Fonctionnement général
03:10 Création des interfaces
06:09 Implémentation du Puzzle
21:20 Génération de l'image (captcha)
34:41 JavaScript, Custom Element
53:00 Intégration dans Symfony

Pourquoi ?

Avant de commencer on peut se demander pourquoi utiliser un système personnalisé alors qu'il existe des solutions toutes faites comme ReCaptcha de Google ou HCaptcha.

Le problème de ces solutions, c'est que ce sont des solutions qui sont tellement généralisées que des services se sont créés autour pour les résoudre de manière plus ou moins optimisée.

Le second problème est la souveraineté des données car pour intégrer ces systèmes de captcha vous devez en général intégrer du JavaScript tiers dans votre page qui peut potentiellement avoir accès à des informations sensibles sur vos utilisateurs (email, nom d'utilisateur et mot de passe).

En revanche, une solution maison va impliquer plus de travail et de tests pour obtenir un résultat qui soit satisfaisant (le moins contraignant pour les utilisateurs tout en étant efficace). Il se pose aussi le problème de l'accessibilité que l'on choisira dans notre cas de gérer à la main si nécessaire.

Principe général

Le principe du captcha est de générer un problème avec une solution qui devra être deviné par un humain. Pour notre cas on va générer une position en X et en Y. On associera à cette valeur une clef que l'on enverra dans le formulaire utilisateur. Cette clef sera ensuite utilisée pour générer un problème difficile à résoudre pour un robot (dans notre cas une image avec un trou à la position indiquée). En complétant le problème l'utilisateur va générer une position que l'on pourra ensuite comparer côté serveur pour savoir si la réponse est satisfaisante et savoir si l'utilisateur est un robot ou non.

sequenceDiagram
    Server->>Server: Génère une clef
    Server->>Client: Formulaire HTML avec clef
    Client->>CaptchaService: Envoie la clef
    CaptchaService->>CaptchaService: Génère le problème
    CaptchaService->>Client: Renvoie le problème
    Client->>Client: Résoud le problème
    Client->>Server: Soumet clef + solution
    Server->>Server: Valide solution

L'interface

Pour notre système on va donc avoir besoin de 2 éléments :

Un système permettant de générer et vérifier une clef

interface ChallengeInterface
{

    public function generateKey(): string;

    public function verify(string $key, string $anwser): bool;

    public function getSolution(string $key): mixed;

}

Un système permettant de générer le problème à partir de la clef

interface ChallengeGenerator
{

    public function generate(string $key): Response;

}

L'implémentation de ces 2 interfaces va dépendre du type de problème que vous souhaitez soumettre à l'utilisateur.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager