Authentification
Notes de cours
- Authentification
- Stockage des mots de passe
- Connexion et déconnexion
- Restriction des accès
Travail personnel
Objectifs
Appliquer les mécanismes du stockage de mot de passe, de l'authentification, et de la restriction d'accès.
Exercice 1 — Bases de l’authentification #
Cette archive contient un fichier comptes.php
,
qui déclare simplement une liste de comptes utilisateur (nom, login, mot de passe, statut)
sous forme de tableaux (un compte = un tableau associatif). Les mots de passe ont été hachés avec l'algorithme bcrypt
,
comme montré en cours.
La liste contient quatre comptes ; le mot de passe des utilisateurs toto
et testeur
est « azerty
»,
celui des deux autres est « 1234
».
Nous allons utiliser ces comptes déjà créés pour faire un mini-site proposant de se connecter/déconnecter, avec en plus une partie réservée aux internautes ayant le statut admin. Le résultat final peut être vu et testé ici : vous pouvez constater que le message de la page d'accueil change si la personne est connectée, et que seul Toto Dupont a accès à la page d'administration. Il n'y a rien d'intéressant sur aucune des pages — seul le mécanisme d'authentification et de droit d'accès nous intéresse dans cet exercice !
Implémentation directe des fonctionnalités
- Créer un script
connexion.php
qui inclutcomptes.php
, et qui affiche un formulaire de connexion (login et mot de passe). La soumission du formulaire doit mener à la même page. - Le script doit analyser les données reçues : si le login existe dans la base et que le mot de passe correspond,
mettre le compte dans une variable de session, par exemple
$_SESSION['user']
. Vous pouvez mettre un feedback comme dans l'exemple si vous voulez, mais ce n'est pas la priorité de l'exercice. - À présent, créer un autre script
index.php
pour la page d'accueil. Le contenu de la page doit être personnalisé si la personne est connectée (par ex. « Bienvenue, Jean-Michel ! »). - Ajouter aux deux pages un menu de navigation avec un lien vers la page d'accueil et un lien vers la page de connexion/déconnexion.
- Modifier
connexion.php
pour que, si la personne est connectée, ce ne soit pas un formulaire de connexion mais un bouton de déconnexion qui soit affiché. Le traitement de la déconnexion est simple : la variable de session est supprimée. Vérifier que la connexion/déconnexion fonctionne correctement, et notamment que la page d'accueil s'adapte. - Créer un script
admin.php
pour simuler une partie admin : la page doit afficher quelque chose comme « partie admin » si la personne est connectée et a le statut d'admin, et doit afficher un message d'erreur comme « accès interdit » sinon. Tester les différents cas. - Mettre à jour les menus :
- Ajouter un menu à la page d'admin, avec des liens vers les trois pages.
- Ajouter un lien vers la page d'admin dans le menu des deux autres pages, mais attention : le lien devra apparaître uniquement aux admins.
- Tester que tout fonctionne correctement avec la checklist suivante :
- si je suis déconnecté·e…
- si je suis connecté·e en tant que
martine
… - si je suis connecté·e en tant que
toto
…
- si je suis déconnecté·e…
Vers un code plus propre et maintenable
Gestion centralisée de l'authentification
À présent que le site fonctionne, on va essayer de nettoyer un peu le code, afin qu'il soit plus modulaire.
Tels quels, les différents scripts fonctionnent indépendamment, tout en partageant un certain nombre de « conventions », en l'occurrence le principe de fonctionnement de la connexion, et le nom de la variable de session associée. Ça peut poser problème lorsqu'il faudra faire évoluer le site, car il est facile d'introduire accidentellement des incompatibilités. Pour commencer, nous allons encapsuler les aspects techniques de l'authentification dans une classe, qui offrira à nos scripts une API plus directe.
- Créer une classe
AuthenticationManager
dans un fichierAuthenticationManager.php
. Son constructeur devra prendre en paramètre une liste de comptes, et elle devra avoir les méthodes suivantes :connectUser($login, $password)
, qui gère la connexion (vérifie si le couple login/password est correct et stocke le compte correspondant en session), et renvoie true si la connexion a réussi (et false sinon)isUserConnected()
qui indique si l'internaute est connecté·e ou nonisAdminConnected()
qui indique si l'internaute est connecté·e avec le statut admingetUserName()
qui renvoie le nom de l'internaute connecté·e ; si l'internaute n'est pas connecté·e, une exception doit être levéedisconnectUser()
qui déconnecte l'internaute
- Modifier les trois scripts du site pour qu'ils créent une instance d'
AuthenticationManager
, et l'utilisent autant que nécessaire : il ne doit plus rester trace de$_SESSION['user']
(ou l'équivalent que vous avez choisi) dans ces scripts — c'est l'AuthenticationManager
qui « a la main » sur ce point.
Gestion centralisée de l'affichage
Un autre problème avec le site est que — à moins que vous n'ayez bien fait les choses — la logique (code PHP) et l'affichage (code HTML) ne sont pas bien séparés, et qu'il y a du code HTML qui est répété à plusieurs endroits. Nous allons maintenant améliorer ça, en centralisant la gestion de l'affichage dans une classe dédiée. Après ça, les trois scripts du site ne contiendront plus que de la logique (donc en l'occurrence quasiment rien…)
- Vérifier que vos pages sont bien valides W3C.
- Créer une nouvelle classe
Displayer
, qui va se charger de tout ce qui concerne l'affichage du site, de façon centralisée. LeDisplayer
va avoir besoin de faire varier l'affichage en fonction du statut de l'internaute (connecté·e ou non, admin ou non) : pour cela, il utilisera une instance deAuthenticationManager
, passée en paramètre à son constructeur.Le
Displayer
aura en particulier les trois méthodes suivantes :displayMainPage()
displayConnectionPage()
displayAdminPage()
displayXYZ
. - Modifier les trois scripts du site pour qu'ils utilisent le
Displayer
. Il ne devrait plus rester grand'chose dans les scripts (sauf, notamment, la récupération des données du formulaire de connexion). Vérifiez que les trois pages sont toujours valides. - Certaines méthodes du
Displayer
font des choix en fonction du statut de l'internaute (connecté·e ou non). Cela peut vite devenir compliqué de s'y retrouver, et de vérifier que les accès autorisés sont bien conformes à ce que l'on veut. Modifier le Displayer pour en faire une classe abstraite ou une interface, avec trois implémentations,PublicDisplayer
(pour les internautes non connecté·es),PrivateDisplayer
(pour les internautes connecté·es) etAdminDisplayer
(pour les admins). Ces trois classes peuvent s'hériter entre elles si vous pensez que c'est utile.