TP REST AUTH
Last updated
Was this helpful?
Last updated
Was this helpful?
Objectifs de ce TP : Implémenter l'authentification dans notre API REST.
Documentation : https://restfulapi.net/security-essentials/
Il existe différents mécanismes pour l'authentification basées sur HTTP Authentication Schemes : Basic, Bearer, Digest ou encore OAuth. Pour une API RESTful, il faut :
utiliser https
que l'authentification soit sans état i.e. l'authentication ne doit pas reposer sur les cookies ou les sessions par exemple.
Dans la suite de ce TP, nous allons modifier notre API REST pour utiliser le standard JWT.
Ce TP s'inspire du tutoriel JWT suivant :
https://www.techiediaries.com/php-jwt-authentication-tutorial/
Certaines requêtes de l'API nécessitent d'être authentifiées pour que le backend exécute ce qui est attendu. Par exemple, une requête de modification d'un utilisateur (PUT /user/{id}
) ne réussira que si l'utilisateur qui envoie cette requête est bien authentifié soit en tant que l'utilisateur id
, soit en tant qu'admin. Si ce n'est pas le cas, une erreur HTTP 401 est retournée par le backend.
Commençons par ajouter un champs USER_PASSWORD
dans la table USER
de la base de données :
Ajouter le champs USER_PASSWORD
dans la table users
de la base de donnée
Vous devez maintenir à jour le fichier sql/createDB.sql
par rapport à votre code PHP. Ce fichier contient le code SQL de création de la base :
Ajouter des utilisateurs dans la base. Attention, il ne faut jamais stocker des mots de passe en clair dans une base de données. Le champs USER_PASSWORD
contiendra donc le hash du mot de passe de l'utilisateur. Un algorithme de hachage est asymétrique c'est-à-dire que l'on peut calculer le hash
d'une chaîne de caractères mais on ne peut pas (ou difficilement) retrouver la chaîne initiale à partir d'un hash
. Dans ce projet, le hash
d'un mot de passe sera calculé en utilisant la méthode BCRYPT
. Vous pouvez calculer le hash d'une chaîne de caractères :
en utilisant un site tel que : https://bcrypt-generator.com/
ou directement avec du code PHP :
Il existe de nombreuses implémentations de JWT. Attention, toutes ne sont pas équivalentes en terme de fonctionnalités, de respect du standard ou encore de bugs. Dans ce projet vous utiliserez (ce n'est pas une assurance que cette bibliothèque soit la meilleure) : https://github.com/firebase/php-jwt
Téléchager le zip du dépôt et décompressez l'archive dans un nouveau répertoire nommé libs
. Renommez les répertoires afin d'obtenir la hiérarchie suivante :
login
et génération d'un token JWTNous allons ajouter un nouvel endpoint POST /login
dans l'API Web :
Ce endpoint nécessite 2 paramètres passés en JSON :
le <login>
de l'utlisateur qui se connecte
<hashed_password>
qui est le hash du mot de passe (la même méthode de hashage doit être utilisée par le back et le front, BCRYPT
dans ce projet).
Si la base contient bien un utilisateur avec l'email <email>
dont le hash du mot de passe est bien <hashed_password>
alors cette requête retournera un code de succès avec un token JWT ou une erreur HTTP. Les hashs doivent être comparés avec la fonction PHP hash_equals
et non pas ==
ou ===
pour éviter des attaques basées sur le temps de comparaison.
Travail à faire :
Ajouter les définitions de 2 nouvelles constantes dans config.php
:
Ajouter controller/LoginController.php
avec le code suivant :
Testez une requête POST /login
avec des identifiants valides afin d'obtenir un token JWT :
Que ce soit pour tester avec Postman ou via le front-end, il faut émettre des requêtes avec le token JWT récupéré en réponse d'une authentification réussie. Ce token doit être passé dans toutes les requêtes nécessitant de l'authentification. Plusieurs solutions possibles pour passer le token JWT dans une requête. Dans ce TP nous utliserons le champs Authorization de l'en-tête de la requête et la méthode Bearer
. Exemple :
Pour tester nous allons implémenter un endpoint temporaire GET /validatetoken
pour tester le décodage du token JWT.
Ajouter la méthode getJwtToken
dans Request
:
Ajouter un controller nommé ValidatetokenController
:
La méthode JWT::decode
décode le contenu du token mais teste également si le token n'a pas expiré. En envoyant une requête correcte avec un token JWT dans le header Authorization
vous devez obtenir les informations stockée dans le token JWT ainsi :
Si vous envoyez une requête sans token JWT ou avec un token erroné, vous devez obtenir :
PUT /user/{id}
Implémenter le endpoint PUT /user/{id}
qui permet de modifier l'email de l'utilisateur {id}
En vous inspirant du code précédent de ValidatetokenController
, modifier ce endpoint pour que seul l'utilisateur authentifié {id}
puisse modifier son email
Mettez à jour la documentation de votre API Web en indiquant les requêtes qui nécessitent d'être authentifié et donc d'envoyer un token JWT.