L'implémentation d'un système d'authentification est une tâche cruciale pour sécuriser une application, en particulier lorsqu'il s'agit de gérer des utilisateurs et leurs données sensibles. Dans cette section, nous allons examiner comment créer un système d'authentification et d'autorisation simple avec FastAPI, tout en utilisant un fichier JSON pour simuler une base de données de MongoDB. Ce système sera composé de deux étapes principales : l'enregistrement et la connexion des utilisateurs.

Le processus commence par l'importation des paquets nécessaires, notamment json et uuid, mais aussi les classes du framework FastAPI, comme APIRouter et la classe personnalisée AuthHandler. Il est important de comprendre que ces paquets sont utilisés principalement pour des fins de démonstration, car dans un environnement de production, vous utiliseriez une base de données comme MongoDB pour gérer les utilisateurs.

Enregistrement d'un utilisateur

Le premier point d'entrée à implémenter est l'endpoint /register, qui permet à un nouvel utilisateur de s'inscrire. Lorsqu'un utilisateur soumet ses informations, celles-ci sont transformées en un modèle UserIn à l'aide de Pydantic. La donnée retournée, quant à elle, est une version allégée de ce modèle, à savoir UserBase, afin d'éviter d'envoyer des informations sensibles comme le mot de passe haché.

Dans ce système de démonstration, au lieu d'utiliser une base de données réelle, nous chargeons les utilisateurs à partir d'un fichier JSON appelé users.json. Ce fichier contient une simple liste d'utilisateurs représentée par un tableau de dictionnaires avec les informations de l'utilisateur (ID, nom d'utilisateur et mot de passe haché). Lorsque l'utilisateur tente de s'enregistrer, nous vérifions si le nom d'utilisateur est déjà pris en le comparant aux utilisateurs existants. Si un doublon est trouvé, une réponse HTTP 409 est envoyée, indiquant que le nom d'utilisateur est déjà pris. Dans le cas contraire, le mot de passe de l'utilisateur est haché et ajouté à la liste des utilisateurs, puis cette liste est sauvegardée dans le fichier JSON.

Connexion de l'utilisateur

Une fois l'utilisateur enregistré, il peut se connecter via l'endpoint /login. Ce processus est assez similaire à celui de l'enregistrement, à l'exception qu'il s'agit ici de valider les informations d'identification d'un utilisateur existant. Nous comparons le nom d'utilisateur fourni avec les données présentes dans notre fichier users.json. Si l'utilisateur n'est pas trouvé ou si le mot de passe ne correspond pas à celui stocké, une exception HTTP 401 est levée avec un message d'erreur générique : "Nom d'utilisateur et/ou mot de passe invalides". Cela respecte les bonnes pratiques de sécurité, où l'on ne spécifie pas lequel des deux éléments est incorrect. Si la vérification est réussie, un jeton JWT (JSON Web Token) est généré et retourné à l'utilisateur. Ce jeton peut ensuite être utilisé pour accéder à des ressources protégées dans l'application.

Ajouter une route protégée

Une fois le système d'enregistrement et de connexion en place, il est essentiel de sécuriser certaines routes afin qu'elles ne soient accessibles qu'aux utilisateurs authentifiés. Cela peut être accompli en utilisant le système d'injection de dépendances de FastAPI. Par exemple, si nous voulons créer un endpoint qui liste tous les utilisateurs, nous pouvons le protéger en exigeant que l'utilisateur soit connecté.

Pour cela, on peut définir une nouvelle route /list dans le fichier users.py. Cette route sera protégée par la dépendance auth_handler.auth_wrapper, qui vérifie si le jeton JWT fourni est valide. Si l'utilisateur est authentifié, la liste des utilisateurs est renvoyée. Dans le cas contraire, une exception sera levée et l'accès sera refusé. Le jeton d'authentification doit être passé dans l'en-tête de la requête HTTP en utilisant le format "Authorization: Bearer {token}".

Test de l'authentification

Il est important de tester correctement le système d'authentification pour s'assurer qu'il fonctionne comme prévu. Cela inclut de tester à la fois l'enregistrement des utilisateurs et leur capacité à se connecter avec un nom d'utilisateur et un mot de passe valides. Utilisez un client HTTP comme HTTPie pour interagir avec l'application et tester l'enregistrement et la connexion des utilisateurs. Par exemple, vous pouvez exécuter une commande comme celle-ci pour enregistrer un utilisateur :

bash
http 127.0.0.1:8000/users/register username="marko" password="marko123"

Le serveur renverra une réponse contenant l'ID de l'utilisateur, son nom d'utilisateur et son mot de passe haché. Vous pouvez ensuite tester la connexion de l'utilisateur en exécutant une commande comme suit :

bash
http POST 127.0.0.1:8000/users/login username="marko" password="marko123"

Cela devrait renvoyer un jeton JWT que vous pourrez utiliser pour effectuer des requêtes protégées.

Résumé et considérations supplémentaires

Il est crucial de noter que ce système d'authentification, bien qu'il soit suffisant pour des fins de démonstration, ne doit pas être utilisé tel quel en production. Dans un environnement réel, vous utiliseriez une base de données pour stocker les utilisateurs et des méthodes de gestion des mots de passe beaucoup plus sécurisées. Par exemple, le fichier JSON est très rudimentaire et n'est pas adapté à un déploiement à grande échelle. De plus, le fait de retourner le mot de passe haché, même dans un système de démonstration, n'est pas une bonne pratique de sécurité. En production, les mots de passe hachés ne doivent jamais être envoyés à l'utilisateur.

L'utilisation de JWT pour l'authentification est une méthode courante et sécurisée pour gérer les sessions utilisateur. Cependant, il est important de s'assurer que les jetons sont protégés et ne peuvent pas être facilement compromis. Une bonne gestion des jetons d'authentification inclut l'utilisation de HTTPS pour les communications réseau et la gestion de l'expiration des jetons.

Pourquoi choisir FastAPI et React pour une architecture moderne de développement web ?

Le développement d'applications web a connu une évolution rapide au fil des années, et le choix des outils pour construire des backends et des frontends n'a jamais été aussi crucial. Parmi les solutions qui se sont récemment imposées dans cet écosystème, FastAPI et React sont deux des choix les plus populaires et efficaces, chacun dans son domaine.

Flask, un microframework Python léger, est une solution puissante pour la création d'APIs REST. Bien que Flask soit souvent utilisé de manière synchrone, il existe une tendance croissante à ajouter une prise en charge asynchrone. Parmi les autres solutions robustes et matures, Tornado se distingue par sa capacité à gérer des milliers de connexions ouvertes de manière asynchrone. Cependant, ces dernières années, une nouvelle génération de solutions basées sur Python a vu le jour, et l'une des plus performantes est sans doute FastAPI. Ce framework asynchrone se base sur Starlette et Pydantic et a été conçu pour offrir des performances exceptionnelles, notamment en exploitant les dernières fonctionnalités de Python, telles que le support des types et des fonctionnalités asynchrones.

FastAPI est aujourd'hui l'un des frameworks web les plus appréciés des développeurs, notamment grâce à sa capacité à intégrer de manière fluide divers composants d'un système. En plus de faciliter les tâches classiques d'un framework web, telles que la gestion des bases de données, l'authentification, et la communication avec le frontend, FastAPI propose une gestion avancée des tâches de fond, la manipulation des entêtes et du corps des requêtes, ainsi que la validation des réponses et des requêtes. Ce framework permet une grande flexibilité et un développement rapide, et ce, sans compromettre la performance.

À côté de cette rapidité de développement et de la prise en charge de fonctionnalités avancées, FastAPI se distingue par sa capacité à générer automatiquement une documentation, ce qui facilite grandement le travail des développeurs et rend l'intégration de nouveaux membres dans une équipe beaucoup plus fluide. Ainsi, lorsque l’on choisit FastAPI, on obtient non seulement une API performante, mais aussi un environnement de développement optimal qui permet une intégration rapide avec d’autres outils et services.

L'une des raisons pour lesquelles FastAPI se distingue est sa capacité à offrir une architecture asynchrone comparable à celle d'un serveur Node.js, mais avec tous les avantages et la richesse de l'écosystème Python. Cela permet de traiter des requêtes de manière rapide et efficace, tout en ayant accès à une multitude de bibliothèques Python pour enrichir l'application.

Le frontend : React

Dans le monde du développement web, les changements sont encore plus visibles lorsqu'il s'agit du frontend, la partie de l'application qui interagit directement avec l'utilisateur. Si les débuts de l'Internet, au début des années 90, étaient marqués par un langage HTML statique et limité, l’arrivée de JavaScript a révolutionné l’interactivité des pages web. Cependant, l'un des tournants majeurs dans ce domaine a été la présentation de React en 2013. Avec son concept de DOM virtuel, son flux de données unidirectionnel et le pattern Flux, React a profondément transformé la manière dont les interfaces utilisateurs sont construites.

React se distingue des autres solutions comme Vue.js ou Svelte.js par sa simplicité et sa flexibilité. Bien qu'il ne soit pas considéré comme un framework complet, mais plutôt comme une bibliothèque, React permet de créer des interfaces utilisateurs dynamiques et performantes en utilisant des composants réutilisables. Son système de JSX, un mélange de JavaScript et XML, permet aux développeurs de concevoir des composants qui encapsulent à la fois la logique et l’interface, facilitant ainsi leur réutilisation dans différentes parties de l'application.

L'un des principaux avantages de React réside dans son performance grâce à son DOM virtuel, qui permet des mises à jour rapides de l'interface sans nécessiter une re-renderisation complète. Les composants React, qui sont conçus pour être réutilisables, contribuent également à réduire la complexité et à accélérer le développement. Grâce à sa gestion du state et à son système de hooks (comme useState), React simplifie la gestion de l’état d’une application tout en permettant une réutilisation efficace de la logique entre différents composants.

L'un des plus grands avantages de React est sa capacité à créer des applications web à page unique (SPA), tout en offrant une prise en charge du rendu côté serveur (SSR), ce qui est essentiel pour l'optimisation du référencement (SEO). Les versions récentes de React ont introduit de nouvelles fonctionnalités, comme les hooks, qui permettent de manipuler l’état et d’autres fonctionnalités des composants sans recourir à des classes, simplifiant ainsi la gestion de l'état et la logique complexe des composants.

Il est important de souligner que, bien que ce livre ne se concentre pas sur React en profondeur, cette technologie est largement utilisée par les développeurs web aujourd'hui. En effet, une étude récente montre qu'environ 81% des développeurs utilisent déjà React dans leurs projets. Cela témoigne de l'adoption massive de cette bibliothèque, non seulement en raison de sa simplicité, mais aussi grâce à son écosystème complet qui inclut des outils comme Next.js et Gatsby.js, permettant de créer des sites statiques ou des applications performantes et évolutives.

Dans le cadre de la création d’une application complète, FastAPI et React forment une combinaison puissante. FastAPI offre un backend asynchrone rapide et flexible, tandis que React permet de créer un frontend dynamique et interactif. Ensemble, ces technologies permettent de construire des applications web modernes, rapides et scalables.

Il convient également de noter que le choix d’une architecture de type FARM (FastAPI + React + MongoDB) permet d'utiliser des technologies open-source et évolutives, tout en bénéficiant de la rapidité et de la simplicité que ces outils offrent. Ce type d'architecture offre également des avantages notables en termes de déploiement sur des plateformes cloud, comme Heroku ou DigitalOcean, et permet d’optimiser les coûts en optant pour des solutions gratuites ou peu coûteuses.