Permettre aux utilisateurs de se connecter à votre application est l’une des fonctionnalités les plus courantes que vous ajouterez à votre application web. Cet article explique comment ajouter une authentification à votre application Flask avec le paquet Flask-Login.
Nous allons créer des pages d’enregistrement et de connexion qui permettent aux utilisateurs de se connecter et d’accéder à des pages protégées que les utilisateurs qui ne sont pas connectés ne peuvent pas voir. Nous prendrons les informations du modèle utilisateur et les afficherons sur nos pages protégées lorsque l’utilisateur se connectera pour simuler à quoi ressemblerait un profil.
Nous aborderons les points suivants dans cet article :
Le code source de ce projet est disponible sur GitHub.
Pour terminer ce tutoriel, vous aurez besoin des éléments suivants :
Notre application utilisera le modèle d’usine de l’application Flask avec des plans. Nous aurons un modèle qui gère tout ce qui est lié à la propriété auth, et nous en aurons un autre pour nos itinéraires réguliers, qui comprennent l’index et la page de profil protégé. Dans une véritable application, vous pouvez décomposer la fonctionnalité comme vous le souhaitez, mais la solution présentée ici fonctionnera bien pour ce tutoriel.
Voici un diagramme qui vous donnera une idée de la structure des fichiers de votre projet une fois que vous aurez terminé le tutoriel :
.
└── flask_auth_app
└── project
├── __init__.py # setup our app
├── auth.py # the auth routes for our app
├── db.sqlite # our database
├── main.py # the non-auth routes for our app
├── models.py # our user model
└── templates
├── base.html # contains common layout and links
├── index.html # show the home page
├── login.html # show the login form
├── profile.html # show the profile page
└── signup.html # show the signup form
Au fur et à mesure que nous avancerons dans le tutoriel, nous créerons ces répertoires et ces fichiers.
Il y a trois paquets principaux dont nous avons besoin pour notre projet :
Nous utiliserons SQLite pour éviter d’avoir à installer des dépendances supplémentaires pour la base de données.
Tout d’abord, nous allons commencer par créer le répertoire des projets :
Ensuite, nous devons naviguer vers le répertoire du projet :
Vous voudrez créer un environnement Python si vous n’en avez pas. Selon la façon dont Python a été installé sur votre machine, vos commandes seront similaires :
Note : vous pouvez consulter le tutoriel adapté à votre environnement local pour la mise en place de venv
.
Exécutez les commandes suivantes depuis votre environnement virtuel pour installer les paquets nécessaires :
Maintenant que vous avez installé les paquets, vous êtes prêt à créer le fichier principal de l’application.
Commençons par créer un répertoire project
:
Le premier dossier sur lequel nous travaillerons sera le fichier __init__.py
pour notre projet :
Ce fichier aura pour fonction de créer notre app, qui initialisera la base de données et enregistrera nos plans. Pour l’instant, cela ne fera pas grand-chose, mais ce sera nécessaire pour le reste de notre application. Nous devons initialiser SQLAlchemy, définir quelques valeurs de configuration et enregistrer nos plans ici.
Maintenant que nous avons le fichier principal de l’application, nous pouvons commencer à ajouter des itinéraires.
Pour nos itinéraires, nous utiliserons deux plans. Pour notre plan principal, nous aurons une page d’accueil (/
) et la page de profil (/profile
) pour après s’être connecté. Si l’utilisateur tente d’accéder à la page de profil sans être connecté, il sera envoyé sur l’intinéraire de connexion.
Pour notre plan d’authentification, nous aurons des itinéraires pour récupérer à la fois la page de connexion (/login
) et la page d’inscription (/sign-up
). Nous aurons également des itinéraires pour traiter les demandes POST provenant de ces deux itinéraires. Enfin, nous aurons un itinéraire de déconnexion (/logout
) pour déconnecter un utilisateur actif.
Pour l’instant, nous allons définir le login
, signup
, et logout
avec des retours simples. Nous les réexaminerons à une étape ultérieure et les mettrons à jour avec la fonctionnalité souhaitée.
Tout d’abord, créez main.py
pour votre main_blueprint
:
Ensuite, créez auth.py
pour votre auth_blueprint
:
Dans un terminal, vous pouvez définir les valeurs FLASK_APP
et FLASK_DEBUG
:
La variable d’environnement FLASK_APP
indique à Flask comment charger l’application. Elle doit indiquer où create_app
est situé. Pour nos besoins, nous indiquerons le répertoire des projets
.
La variable d’environnement FLASK_DEBUG
est activée en lui donnant la valeur 1
, ce qui activera un débogueur qui affichera les erreurs de l’application dans le navigateur.
Assurez-vous que vous êtes dans le répertoire flask_auth_app
et puis exécutez le projet :
Maintenant, dans un navigateur web, vous devriez être en mesure de naviguer vers les cinq URL possibles et voir le texte renvoyé qui a été défini dans auth.py
et main.py
.
Par exemple, visiter localhost:5000/profile
affiche : Profile
:
Maintenant que nous avons vérifié que nos itinéraires se comportent comme prévu, nous pouvons passer à la création de modèles.
Allons de l’avant et créons les modèles qui sont utilisés dans notre application. C’est la première étape avant que nous puissions mettre en œuvre la fonctionnalité de connexion proprement dite. Notre application utilisera quatre modèles :
Nous aurons également un modèle de base qui aura un code commun à chacune des pages. Dans ce cas, le modèle de base sera doté de liens de navigation et de la disposition générale de la page. Créons-les maintenant.
Tout d’abord, créez un répertoire de modèles
sous le répertoire de project
:
Ensuite, créez base.html
:
Ensuite, ajoutez le code suivant au fichier base.html
:
Ce code créera une série de liens de menu vers chaque page de l’application et une zone où le contenu apparaîtra .
Remarque : En arrière-plan, nous utilisons Bulma pour s’occuper du style et de la mise en page. Pour une plongée plus approfondie dans Bulma, pensez à lire la documentation officielle de Bulma.
Ensuite, créez templates/index.html
:
Ajoutez le code suivant au fichier nouvellement créé pour ajouter du contenu à la page :
Ce code permettra de créer une page d’index de base avec un titre et un sous-titre.
Ensuite, créez templates/login.html
:
Ce code génère une page de connexion avec des champs pour Email et Password. Il y a également une case à cocher pour « se souvenir » d’une session connectée.
Ensuite, créez templates/signup.html
:
Ajoutez le code suivant pour créer une page d’inscription avec des champs pour email, name, et password :
Ensuite, créez templates/profile.html
:
Ajoutez ce code pour créer une page simple avec un titre codé en dur pour accueillir Anthony:
Plus tard, nous ajouterons du code pour saluer dynamiquement tout utilisateur.
Une fois que vous avez ajouté les modèles, nous pouvons mettre à jour les déclarations de retour dans chacun des itinéraires ; nous devons renvoyer les modèles au lieu du texte.
Ensuite, mettez à jour main.py
en modifiant la ligne d’importation et les itinéraires pour index
et profile
:
Vous allez maintenant mettre à jour auth.py
en modifiant la ligne d’importation et les itinéraires pour login
et signup
:
Une fois que vous avez effectué ces changements, voici à quoi ressemble la page d’inscription si vous naviguez vers /signup
:
Vous devriez pouvoir voir également les pages pour /
, /login
et /profile
.
Nous laisserons /logout
seul pour l’instant car il n’affichera pas de modèle quand il sera terminé.
Notre modèle d’utilisateur représente ce que cela signifie pour notre app d’avoir un utilisateur. Nous aurons des champs pour une adresse électronique, un mot de passe et un nom. Dans votre application, vous pouvez décider que vous souhaitez que beaucoup plus d’informations soient stockées par utilisateur. Vous pouvez ajouter des éléments tels que l’anniversaire, la photo de profil, la localisation ou toute autre préférence de l’utilisateur.
Les modèles créés dans Flask-SQLAlchemy sont représentés par des classes qui sont ensuite traduites en tables dans une base de données. Les attributs de ces classes se transforment alors en colonnes pour ces tables.
Allons de l’avant et créons ce modèle d’utilisateur :
Ce code crée un modèle d’utilisateur avec des colonnes pour un id
, email
, password
et un name
:
Maintenant que vous avez créé un modèle d’utilisateur, vous pouvez passer à la configuration de votre base de données.
Comme indiqué dans les conditions préalables, nous utiliserons une base de données SQLite. Nous pourrions créer nous-mêmes une base de données SQLite, mais laissons Flask-SQLAlchemy le faire pour nous. Nous avons déjà le chemin de la base de données spécifié dans le fichier__init__.py
,il suffit donc de dire à Flask-SQLAlchemy de créer la base de données dans le REPL Python.
Si vous arrêtez votre application et ouvrez un REPL en Python, nous pouvons créer la base de données en utilisant la méthode create_all
sur l’objet db
. Assurez-vous que vous êtes toujours dans l’environnement virtuel et dans le répertoire flask_auth_app
.
Note : Si l’utilisation de l’interpréteur Python est nouvelle pour vous, vous pouvez consulter la documentation officielle.
Vous allez maintenant voir un fichier db.sqlite
dans le répertoire de votre projet. Cette base de données contiendra notre table d’utilisateurs.
Pour notre fonction d’inscription, nous allons prendre les données que l’utilisateur tape dans le formulaire et les ajouter à notre base de données. Avant de les ajouter, nous devons nous assurer que l’utilisateur n’existe pas déjà dans la base de données. Si ce n’est pas le cas, nous devons nous assurer que nous avons bien haché le mot de passe avant de le placer dans la base de données, car nous ne voulons pas que nos mots de passe soient stockés en clair.
Commençons par ajouter une deuxième fonction pour traiter les données du formulaire POST. Dans cette fonction, nous allons d’abord recueillir les données transmises par l’utilisateur.
Créez la fonction et ajoutez une redirection vers le bas. Cela permettra à l’utilisateur de faire l’expérience d’une inscription réussie et d’être dirigé vers la page de connexion.
Mettez à jour auth.py
en modifiant la ligne d’importation et en mettant en œuvre signup_post
:
Maintenant, ajoutons le reste du code nécessaire à l’inscription d’un utilisateur.
Pour commencer, nous devrons utiliser l’objet de demande pour obtenir les données du formulaire.
Continuez à mettre à jour auth.py
en ajoutant des importations et en mettant en œuvre signup_post
:
Remarque : Le stockage des mots de passe en clair est considéré comme une mauvaise pratique de sécurité. Vous voudrez généralement utiliser un algorithme de hachage complexe et un sel de mot de passe pour assurer la sécurité des mots de passe.
Maintenant que la méthode d’inscription est terminée, nous devrions être en mesure de créer un nouvel utilisateur. Utilisez le formulaire pour créer un utilisateur.
Il y a deux façons de vérifier si l’inscription a fonctionné : vous pouvez utiliser un visualiseur de base de données pour regarder la ligne qui a été ajoutée à votre table, ou vous pouvez essayer de vous inscrire à nouveau avec la même adresse électronique, et si vous obtenez une erreur, vous savez que le premier courriel a été enregistré correctement. Adoptons donc cette approche.
Nous pouvons ajouter un code pour faire savoir à l’utilisateur que le courriel existe déjà et lui dire de se rendre à la page de connexion. En appelant la fonction flash
, nous enverrons un message à la demande suivante, qui dans ce cas, est la redirection. La page sur laquelle nous arrivons aura alors accès à ce message dans le modèle.
D’abord, nous ajoutons le flash
avant de rediriger vers notre page d’enregistrement.
Pour obtenir le message clignotant dans le modèle, nous pouvons ajouter ce code au-dessus du formulaire. Le message s’affichera alors directement au-dessus du formulaire.
La méthode de connexion est similaire à la fonction d’inscription en ce sens que nous prenons les informations de l’utilisateur et en faisons quelque chose. Dans ce cas, nous comparerons l’adresse électronique saisie pour voir si elle se trouve dans la base de données. Si c’est le cas, nous testerons le mot de passe fourni par l’utilisateur en hachant le mot de passe que l’utilisateur nous a communiqué et en le comparant au mot de passe haché dans la base de données. Nous savons que l’utilisateur a saisi le bon mot de passe lorsque les deux mots de passe hachés correspondent.
Une fois que l’utilisateur a passé le contrôle du mot de passe, nous savons qu’il possède les bonnes références et nous pouvons le connecter en utilisant Flask-Login. En appelant login_user
, Flask-Login créera une session pour cet utilisateur qui persistera tant que l’utilisateur restera connecté, ce qui lui permettra de voir les pages protégées.
Nous pouvons commencer par un nouveau mode de traitement des données POSTed. Nous redirigerons vers la page de profil lorsque l’utilisateur se connectera avec succès :
Maintenant, nous devons vérifier si l’utilisateur possède les bons identifiants
Ajoutons le bloc dans le modèle pour que l’utilisateur puisse voir le message clignotant. Comme pour le formulaire d’inscription, ajoutons le message d’erreur potentiel directement au-dessus du formulaire :
Nous avons maintenant la possibilité de dire qu’un utilisateur a été connecté avec succès, mais il n’y a rien pour connecter l’utilisateur. C’est là que nous introduisons Flask-Login pour gérer les sessions des utilisateurs.
Avant de commencer, nous avons besoin de quelques éléments pour que Flask-Login fonctionne. Commencez par ajouter le UserMixin
à votre modèle User. Le UserMixin
ajoutera les attributs de Flask-Login au modèle afin que Flask-Login puisse travailler avec lui.
Ensuite, nous devons spécifier notre chargeur d’utilisateurs. Un chargeur d’utilisateur indique à Flask-Login comment trouver un utilisateur spécifique à partir de son identifiant stocké dans son cookie de session. Nous pouvons l’ajouter dans notre create_app
ainsi que le code init
du Flask-Login :
Enfin, nous pouvons ajouter le login_user
juste avant de rediriger vers la page de profil pour créer la session :
Avec la configuration de Flask-Login, nous pouvons utiliser l’itinéraire /login
. Lorsque tout est en place, vous verrez la page de profil.
Si votre nom n’est pas aussi Anthony, alors vous verrez que votre nom est faux. Ce que nous voulons, c’est que le profil affiche le nom dans la base de données. Nous devons donc d’abord protéger la page et ensuite accéder aux données de l’utilisateur pour obtenir le nom.
Pour protéger une page lors de l’utilisation de Flask-Login, nous ajoutons le décorateur @login_required
entre l’itinéraire et la fonction. Cela empêchera un utilisateur qui n’est pas connecté de voir l’itinéraire. Si l’utilisateur n’est pas connecté, il sera redirigé vers la page de connexion, selon la configuration du Flask-Login.
Avec les itinéraires qui sont décorés avec le décorateur @login_required
, nous avons alors la possibilité d’utiliser l’objet current_user
à l’intérieur de la fonction. Ce current_user
représente l’utilisateur de la base de données, et nous pouvons accéder à tous les attributs de cet utilisateur avec la notation par points. Par exemple, current_user.email
, current_user.password
, et current_user.name
, et current_user.id
renverront les valeurs réelles stockées dans la base de données pour l’utilisateur connecté.
Utilisons le nom de l’utilisateur actuel et envoyons-le au modèle. Nous utiliserons alors ce nom et afficherons sa valeur.
Ensuite, dans le fichier profile.html
, mettez à jour la page pour afficher la valeur name
:
Une fois que nous nous rendons sur notre page de profil, nous voyons alors que le nom de l’utilisateur apparaît.
La dernière chose que nous pouvons faire est de mettre à jour la vue de déconnexion. Nous pouvons appeler le logout_user
dans un itinéraire de déconnexion. Nous avons le décorateur @login_required
parce qu’il n’est pas logique de déconnecter un utilisateur qui n’est pas connecté au départ.
Lorsque nous nous déconnectons et que nous essayons de consulter à nouveau la page de profil, nous voyons apparaître un message d’erreur. C’est parce que Flask-Login fait clignoter un message pour nous lorsque l’utilisateur n’est pas autorisé à accéder à une page.
Une dernière chose que nous pouvons faire est de mettre des déclarations if
dans les modèles pour afficher uniquement les liens pertinents pour l’utilisateur. Ainsi, avant que l’utilisateur ne se connecte, il aura la possibilité de se connecter ou de s’inscrire. Une fois que l’on se connecte, on peut aller sur son profil ou se déconnecter :
Grâce à cela, vous avez réussi à construire votre application avec authentification.
Nous avons utilisé Flask-Login et Flask-SQLAlchemy afin de créer un système de connexion pour notre app. Nous avons abordé la manière d’authentifier un utilisateur en créant d’abord un modèle d’utilisateur et en stockant les informations sur l’utilisateur. Ensuite, nous avons dû vérifier que le mot de passe de l’utilisateur était correct en hachant le mot de passe du formulaire et en le comparant à celui stocké dans la base de données. Enfin, nous avons ajouté l’autorisation à notre app en utilisant le décorateur @login_required
sur une page de profil afin que seuls les utilisateurs connectés puissent voir cette page.
Ce que nous avons créé dans ce tutoriel sera suffisant pour les petites applications, mais si vous souhaitez avoir plus de fonctionnalités dès le début, vous pouvez envisager d’utiliser les bibliothèques Flask-User ou Flask-Security qui sont toutes deux construites sur la bibliothèque Flask-Login.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Super tutoriel merci.
J’ai remarqué qu’il manque l’attribut name=“remember” dans le html pour le login.
Meilleures salutations.
Merci pour ce tuto très clair ! Par contre je ne m’explique pas pourquoi maintenant que je lance mon appli j’ai une erreur sur les dépendances circualires (init.py qui importe User qui importe db depuis le module courant, donc init.py ?) alors que en suivant le tuto je n’avais aucun soucis (peut-être le mode DEVELOPPER qui fait du lazy reload ?)
Une idée sur l’erreur de dépendance circulaire ? J’ai bien relu tous les import, je ne trouve pas mon erreur.
Merci beaucoup pour ce tuto bien expliqué et détaillé.