L'authentification à deux facteurs peut sembler être un processus très banal de la part de l'utilisateur. Beaucoup sont habitués depuis longtemps au fait que, lorsqu'ils utilisent de nombreuses applications, il ne suffit pas de saisir une combinaison familière de login et de mot de passe. Un facteur de vérification supplémentaire est introduit pour renforcer la sécurité et empêcher tout accès non autorisé. Dans la plupart des cas, il s'agit d'un code unique qui peut être reçu par e-mail ou par SMS.
Dans ce tutoriel, nous allons apprendre comment mettre en œuvre l'authentification à deux facteurs dans AppMaster. A titre d'exemple, l'envoi du code par mail sera utilisé. Nous analyserons quels modules doivent être connectés, quels réglages effectuer, quel processus d'entreprise créer et comment vérifier le résultat final dans la pratique.
Tout d'abord, jetons un coup d'œil au plan général. Quelles sont les étapes à mettre en œuvre dans notre processus opérationnel ?
- Vérification de la connexion (s'assurer que l'utilisateur est réellement enregistré).
- Vérification de l'exactitude du mot de passe.
- Envoi d'un code de confirmation par courrier ou SMS.
- Vérification de la pertinence du code.
- Vérification de l'exactitude du code.
- Сompletion de l'authentification.
Phase préparatoire
Avant même de commencer à concevoir l'authentification à deux facteurs, au stade de l'enregistrement des utilisateurs, vous devez vous assurer que :
- Les données de l'utilisateur doivent contenir un e-mail. Il sera utilisé pour envoyer le code de vérification. L'e-mail est souvent utilisé comme identifiant, et nous allons examiner un tel exemple.
- Le login est unique. Deux utilisateurs différents avec le même login ne peuvent pas exister dans le système.
Pour faciliter la résolution de ces tâches (et de bien d'autres), le module Auth est installé par défaut dans chaque projet AppMaster. Il contient les modèles de base de données, les blocs de processus métier et les points d'extrémité nécessaires à leur utilisation.
Vérification du login
Le login, le mot de passe et le code de vérification sont utilisés comme paramètres d'entrée du processus d'entreprise. Mais à la première étape, nous n'avons besoin que d'un login. Il serait utile de s'assurer que cet utilisateur existe. Il a été enregistré, et les informations le concernant sont stockées dans la base de données.
Pour ce faire, le bloc DB: Search User recherche un utilisateur avec le login donné dans la base de données. Veillez à définir le paramètre SearchExact = True pour rechercher une correspondance exacte.
Les données reçues sont transmises au bloc Array Element avec l'index 0 (le comptage commence à zéro, et la seule valeur trouvée correspondra toujours à l'index 0 dans le tableau).
Le bloc Is Null vérifie si l'utilisateur a effectivement été trouvé. Et en fonction du résultat (True/False), le bloc If-Else interrompt le processus métier avec un message d'erreur (Raise Error ) ou le diriger plus loin.
Vérification du mot de passe
À ce stade, il faut s'assurer que le mot de passe de l'utilisateur est saisi correctement.
Et ici, il est essentiel de comprendre que les mots de passe ne sont pas stockés explicitement dans la base de données. La fonction Bcrypt les hachent, et seul le hachage résultant est stocké dans la base de données. Par conséquent, même si nous supposons qu'une fuite de données se produira, les attaquants ne seront toujours pas en mesure de trouver les mots de passe des utilisateurs ; ils sont chiffrés de manière sécurisée.
Pour cette raison, vous ne pouvez pas simplement récupérer le mot de passe dans la base de données et le comparer au mot de passe saisi. Vous devez obtenir le hachage du mot de passe et l'utiliser pour la comparaison. Pour résoudre ce problème, le bloc Auth: Probe Password est utilisé. Il prend comme paramètres d'entrée le mot de passe saisi par l'utilisateur (password) et le hachage du mot de passe stocké dans la base de données (hashed_password) et les convertit en type de données String (le bloc To String ).
En fonction du résultat, comme dans l'étape précédente, en utilisant le bloc If-Else nous affichons un message d'erreur (Raise Error, Message = Password is wrong) ou bien nous dirigeons le processus vers l'étape suivante.
Extension du modèle de l'utilisateur
Pour l'étape suivante, vous devez apporter une petite modification au modèle utilisateur et ajouter des informations sur le code qui doit être confirmé.
En général, le modèle User contient initialement des champs qui peuvent être utilisés pour cette tâche - Confirmed, Confirmation code, Confirmation code expires at. Mais dans cet exemple, nous supposerons que ces champs ne sont utilisés que pour l'inscription et la vérification initiale du compte.
Pour une plus grande clarté du processus, créons un modèle séparé twofa (two-factor authentication), associons-y le modèle User (relation 1 à 1, has one), et ajoutons un champ - code ( typeString ).
Préparation de l'envoi d'e-mails
Pour envoyer des e-mails avec des codes de confirmation, il faut se préparer au préalable. L'une des options les plus accessibles est d'utiliser le module Custom SMTP qu'il faut installer et configurer.
Lorsque vous utilisez Gmail, la plupart des paramètres sont déjà définis par défaut, et vous devez ajouter votre nom d'utilisateur et votre mot de passe. Si vous utilisez d'autres serveurs de messagerie, il serait utile de vous référer à leur documentation pour obtenir les données nécessaires.
Dans ce cas, vous devrez peut-être modifier légèrement les paramètres de sécurité du serveur de messagerie. Par exemple, Gmail peut bloquer par défaut les connexions utilisant des applications tierces, et vous devez supprimer cette restriction dans les paramètres.
Envoi d'un code de vérification
Nous avons vérifié le login et le mot de passe et effectué toutes les préparations nécessaires, vous pouvez donc maintenant procéder à l'envoi d'une lettre avec un code de confirmation.
Le bloc Custom SMTP: Send Email utilise un tableau d'adresses comme destination. Par conséquent, même si vous devez envoyer une lettre à une seule adresse, celle-ci doit être ajoutée au tableau. Pour cela, le bloc Append Array est utilisé.
L'étape suivante consiste à générer un code de vérification. Le bloc Random string convient pour cela. Nous allons envoyer un code composé de 6 nombres aléatoires et effectuer les réglages appropriés. Length = 6, With 0-9 = True, tous les autres paramètres = False.
Ensuite, vous devez créer le texte de la lettre. Pour ce faire, utilisez le bloc Concat Strings pour ajouter un texte explicatif au code généré (First = Verification code: ), convertissez le résultat en type de données Text (blocTo Text ), et connectez le résultat au paramètre body du bloc d'envoi du courrier électronique.
Pour l'envoi final, il ne reste plus qu'à préciser l'objet de la lettre (subject) et l'expéditeur (from_name).
Mais il ne suffit pas d'envoyer le code, il faut aussi le stocker dans les données de l'utilisateur. En effet, vous devez vérifier son exactitude lorsque l'utilisateur reçoit le code et le renvoie en guise de confirmation.
Pour ce faire, nous allons utiliser le modèle twofa, que nous avons prudemment créé précédemment. S'il s'agit de la première soumission de code, vous devez le créer avec des informations sur l'utilisateur auquel il appartient. En cas de réutilisation, il est nécessaire de patcher l'entrée existante, en indiquant son ID et son nouveau code.
La dernière étape de l'étape consiste à utiliser le bloc Raise Error pour renvoyer un message sur l'envoi du code à l'e-mail.
Contrôle de la pertinence du code
Il est intéressant de prendre soin d'une sécurité supplémentaire et de protéger le code d'une énumération banale. Il serait judicieux de limiter le nombre de tentatives de saisie, leur fréquence et la durée de vie du code soumis. Nous n'analyserons pas tous ces exemples ; les exigences de sécurité sont propres à chaque projet et peuvent inclure de nombreuses conditions différentes. Nous nous limitons à vérifier la pertinence du code par sa période de validité.
Utilisons le bloc Current date & time pour obtenir l'heure actuelle. Connectez-le au paramètre B du bloc Date & time difference du bloc. Nous utiliserons le champ UpdatedAt du modèle twofa comme paramètre A.
En conséquence, nous obtenons Time span - la différence entre deux points de temps. Il ne reste plus qu'à vérifier si cette différence dépasse une certaine valeur choisie. Dans notre exemple, il s'agit de 5 minutes, que nous définirons comme la valeur statique B du bloc Greater bloc.
Le bloc If-Else utilisera le résultat de la comparaison pour guider la suite du processus. Si True (la différence dépasse 5 minutes), le processus reviendra à l'étape d'envoi de la lettre ; l'utilisateur recevra un code actualisé. Dans le cas où False (le code est frais et à jour), il sera possible de procéder à la vérification de ce code.
Vérification du code
La dernière étape de l'authentification consiste à vérifier le code reçu.
Le bloc Equal doit valider que le code transmis par l'utilisateur correspond au code stocké dans le modèle twofa associé à l'utilisateur. Si ce n'est pas le cas et que le code est mal spécifié (If-Else -> False), il faut alors afficher un message d'erreur (Raise Error, Message = Code is wrong). Si la comparaison confirme la correspondance, vous pouvez passer à l'étape d'authentification finale.
Pour ce faire, nous utilisons le bloc Auth: Authentication et obtenons des informations sur l'utilisateur avec son jeton d'autorisation. Nous les transmettons au bloc End comme résultat d'une authentification réussie.
Création d'un endpoint
Le processus métier a été créé mais n'est pas encore disponible pour être utilisé. Vous devez créer un endpoint qui exécutera ce processus d'affaires.
Une solution raisonnable serait d'utiliser le terminal d'authentification par défaut (POST /Auth). Il suffira de remplacer son processus métier et d'installer celui qui vient d'être créé. Ainsi, l'authentification simple sera désactivée, et l'authentification à deux facteurs sera utilisée à la place.
Publication et test
La création de l'authentification à deux facteurs est ainsi terminée. Vous pouvez publier le résultat et le vérifier en action. Pour cela, il est pratique d'utiliser Swagger, accessible en cliquant sur le nom du plan Deploy dans la section Project API du bouton Preview.
Il ne reste plus qu'à trouver le point d'extrémité souhaité dans la liste, à saisir les données utilisateur et à lancer l'exécution avec le bouton Execute. Si des erreurs sont constatées lors du test, il faut alors revenir au processus métier et apporter les modifications nécessaires.