Skip to content
Snippets Groups Projects
Commit 62ef66f6 authored by BURCKEL LUC's avatar BURCKEL LUC
Browse files

add tp6

parent 0e53c404
No related merge requests found
SSH et Giltab
=============
Cette procédure permet d'utiliser l'authentification par clé SSH plutôt que de taper ses login et mot de passe à chaque requête vers Gitlab (push, pull, etc.). Elle comporte deux étapes détaillées ci-dessous :
1. Créer une clé SSH pour votre compte utilisateur
2. Copier la clé publique dans Gitlab
Si vous utilisez Gitlab à partir de plusieurs comptes (ordi de l'IUT, ordi perso, etc.), la procédure suivante est à répéter pour chaque compte.
1 - Créer une clé SSH
---------------------
1. Dans un terminal, tapez la commande suivante :
```
login@ordi:~$ ssh-keygen -b 4096 -C [nom de la clé]
```
Pour chaque question, laissez vide et validez :
```
Generating public/private rsa key pair.
Enter file in which to save the key (/.../login/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /.../login/.ssh/id_rsa.
Your public key has been saved in /.../login/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:f3FTQpO9zwSY4DS2rIc1qT687x9C8CsuTD8MB61ogyU [nom de la clé]
The key's randomart image is:
+---[RSA 4096]----+
| =. ooo |
| B = +o.o..|
| .. B ..o|
| E . . .B . +.|
| + . oS + . oo.|
| . + +o.+ . o .o|
| . + == + o |
| o.++ o . |
| .o+o.. |
+----[SHA256]-----+
```
2. Deux fichiers (au moins) sont alors créés dans votre répertoire `/.../login/.ssh/` :
```
login@ordi:~$ ls ~/.ssh
... id_rsa id_rsa.pub ...
```
- `id_rsa` contient votre clé privé : ne jamais la communiquer !
- `id_rsa.pub` contient votre clé publique : vous pouvez la communiquer au monde entier.
2 - Copier la clé publique dans Gitlab
--------------------------------------
*Un GIF illustrant les 8 points suivants est disponible dans `images/sshGitlab.gif`.*
1. Connectez-vous sur Gitlab avec vos identifiants Unistra : https://git.unistra.fr
2. Cliquez sur l'icône en haut à droite de l'écran
3. Cliquez sur le menu "Settings" ("Paramètres")
4. Dans le menu à gauche de l'écran, cliquez sur le menu "SSH Keys" ("Clés SSH")
5. Dans un terminal, affichez votre clé avec la commande suivante :
```
login@ordi:~$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3GZATo37T8jZVwV14k3luTLmXZUaKeUVFxqBBOow+0i1FcHmDEakdmTC6gz5iZt/o7oht8bdFFDxkroM7IkpiJ7Yb4WGBfhnw232L7U8oWb/4Wu17JZ/qeMXmUwZuSk7utX0ucW9SKOuTPID1qtJXOTrqSiiueK4BmPtAQEVI0DB5lo1q4/RNQwLAuGU06i2B9k+Fk6NWjcbWoDyNltbyvmosCpmmjNXYxiCP6GYYnEeUUBkZGoMRhwcZCG0tSm26X9oUqkauD8daY9Y+0W6xysrkEe2HVb+Aqv2ljV+L1Vnftor1VuhAwQD+LPAmUGoh2VcWMT37lOWxYOYLbf93rTwcPZKGsGQwljwVdl4cfK6+UzNU2h4/u1+YvNtEBj2eVw55AQPz34IMXmiBTa4MuKSBp9Di0ZWfiAjNEzHvzxC7l9+Uqfo/YlEWnGocfrci0dPXGJGaRNEF85BIIm+YkmMP2LRbKgCLYt3x8a/7ba56barUWs9N5rjFZ1BikPfCBCuTXR8rX/8RKBQQj0g/yqoTg6TggQ6jou5U5oQ54NpSCQZntIJ6b8ub+V9Cni1NWmURoBqEDnoxXomGJokJLhwMNqHi0Quc5OMSbZW9CNaNbv5uPrZxNfcfnD5pA0LhId3S2VlS/YxCc8iYyPj6vDwBZw43ipwk2tU8pOOHAQ== [nom de la clé]
```
6. Copiez-collez votre clé `ssh-rsa AAAA...AQ== [nom de la clé]` dans le champ "Key" ("Clé") sur Giltab
7. Cliquez sur le bouton "Add key" ("Ajouter la clé")
8. C'est terminé : vous recevez dans la foulée un mail vous indiquant qu'une clé ssh a été ajoutée.
"*M'sieur, comment...*
======================
#### *... j'affiche l'état de mon clône ?"*
```sh
git status
```
#### *... j'ajoute des fichiers à prendre en compte au prochain commit ?"*
```sh
git add [file]
```
#### *... je commite (sauvegarde localement) mes modifications ?"*
```sh
git commit -m "[message qui DÉTAILLE les modifications]"
```
ATTENTION : Seuls les fichiers préalablement ajoutés seront sauvegardés.
#### *... je pousse mes commits sur Gitlab (sauvegarde distante) ?"*
```sh
git push origin master
```
#### *... je récupère localement les fichiers que vous avez ajouté ?"*
```sh
git pull prof master
```
#### *... je récupère sur ordinateur2 ce que j'ai fait sur ordinateur1 ?"*
1. Je **commite** sur ordinateur1 et **pousse** vers Gitlab (voir ci-dessus)
2. Je **tire** sur ordinateur2 ce qui est maintenant sur Gitlab
```sh
git pull origin master
```
Serveur PHP local
=================
Pour l'environnement de travail, l'utilisation d'une usine à gaz comme LAMP ou WAMP est inutile : vous n'avez besoin que de PHP.
Installation sur une ordinateur personnel
-----------------------------------------
### Sous windows
**L'utilisation d'une distribution Linux est fortement recommandée.** Il n'y a pas de méthode "simple" sous Windows. Deux solutions :
1. Installer une distribution Linux en Dual Boot
2. Installer une machine virtuelle avec une distribution Linux => ici [un tuto pour installer Ubuntu avec Hyper-V](https://www.windowscentral.com/how-run-linux-distros-windows-10-using-hyper-v)
### Sous Linux
Il vous faut les droits root pour installer l'ensemble des paquets dont vous aurez besoin en une seule commande :
```bash
$ sudo apt install php sqlite3 php-sqlite3 sqlitebrowser composer
```
Utilisation
-----------
> *Cette procédure remplace l'utilisation de `public_html` et `webetu`.*
Ce qui suit peut être réalisé :
- sur votre ordinateur personnel si vous avez réalisé l'installation de la section précédente
- sur un bureau à distance de l'IUT depuis `troglo`, `phoenix` ou `cannette`
### Lancement d'un serveur local
La procédure à suivre pour lancer un serveur PHP local est détaillée [dans la doc de PHP](https://www.php.net/manual/fr/features.commandline.webserver.php) dont voici un résumé :
0. On suppose que le répertoire `/chemin/vers/mon/repertoire/de/TP/` sera la racine de l'ensemble des fichiers de votre TP.
1. Ouvrir un terminal
2. Lancer un serveur local dont la racine est ce répertoire :
```bash
$ php -S localhost:port -t /chemin/vers/mon/repertoire/de/TP/
```
avec `port` un entier compris entre 1025 et 65535. Si vous avez un message d'erreur, essayez un autre port.
### Accéder au serveur local depuis un navigateur
Pour visualiser le rendu d'un fichier PHP par le serveur que vous avez lancé, il suffit d'ouvrir un navigateur à cette URL :
**`http://localhost:port`**
et d'ajouter son chemin à la fin de l'URL.
##### Exemples :
| Fichier à visualiser | URL |
|--------------------------------------------------------|----------------------------------------------|
| `/chemin/vers/mon/repertoire/de/TP/signin.php` | `http://localhost:port/signin.php` |
| `/chemin/vers/mon/repertoire/de/TP/rep1/rep2/test.php` | `http://localhost:port/rep1/rep2/signin.php` |
W31 - Programmation web côté serveur
====================================
#### IMPORTANT : Il sera impératif de savoir utiliser ce dépôt pour le TP noté.
Pour démarrer, vous devez :
1. Mettre en place une clé SSH en suivant le tuto [GITLABSSH.md](GITLABSSH.md)
2. Mettre en place votre environnement de travail en suivez les instructions ci-dessous.
Ensuite, pour **utiliser** de votre dépôt, regardez la page [HOWTO.md](HOWTO.md).
#### Les diapos des cours :
- [CM n°1 : Introduction à PHP](http://adrien.krahenbuhl.fr/courses/IUTRS/W31/CM1)
- [CM n°2 : POO et PDO](http://adrien.krahenbuhl.fr/courses/IUTRS/W31/CM2)
- [CM n°3 : Laravel](http://adrien.krahenbuhl.fr/courses/IUTRS/W31/CM3)
#### Moodle
- [Le cours sur BBB](https://moodle3.unistra.fr/mod/bigbluebuttonbn/view.php?id=365399)
- [Les quizz](https://moodle3.unistra.fr/course/view.php?id=6423)
1 - Créer un **clône distant** sur Gitlab
-----------------------------------------
Il suffit de cliquer sur le bouton "Fork" en haut de la page, à côté du bouton bleu "Clone".
**À FAIRE** : Ajouter votre enseignant de TP en tant que "Reporter" de votre dépôt (menu "Members").
2 - Créer un **clône local** sur votre ordinateur
-------------------------------------------------
1. Installer git sur votre ordinateur personnel (rien à faire sur les postes de l'IUT) :
```sh
$ sudo apt install git
```
2. Configurer vos informations d'utilisateur :
```sh
$ git config --global user.name "[Prenom] [Nom]"
$ git config --global user.email "[login]@unistra.fr"
```
3. Cloner votre fork :
```sh
$ git clone git@git.unistra.fr:[login]/W31.git
```
3 - Ajouter le **remote "prof"**
--------------------------------
En trois commandes :
```sh
$ cd W31
$ git remote add prof https://git.unistra.fr/W31/w31.git
$ git fetch prof
```
Si tout s'est bien passé, la commande :
```sh
$ git remote
```
affiche :
```sh
origin
prof
```
TP n°1 : requêtes GET/POST, cookies et sessions
===============================================
Tous vos fichiers PHP devront être déposés dans le répertoire `public_html` à la racine de de votre répertoire personnel. Il sera ainsi accessible à l'adresse `https://webetu.iutrs.unistra.fr/~[LOGIN_UNISTRA]/chemin_vers_le_fichier`.
Exemple :
- Mon pseudo unistra est `jdupont`
- Je dépose le fichier `test.php` dans le répertoire `jdupont/public_html/TP1/`
- Je peux visualiser mon fichier interprété par le serveur PHP à l'adresse `https://webetu.iutrs.unistra.fr/~jdupont/TP1/test.php`
Exercice 1 - Bonjour
--------------------
1. Écrivez un fichier PHP `bonjour.php` qui contient uniquement du code HTML5 **valide**. Visualisez-le avec Postman puis avec votre navigateur.
2. Écrivez un fichier `bonjourGet.php` qui contient la structure de base d'un fichier HTML5 valide.
- Dans le `<body>`, ajoutez du code PHP qui affiche le contenu de la variable `module` du tableau `$_GET`.
- Testez avec Postman et votre navigateur, en transmettant ou non une variable via la méthode `GET`.
- Ajoutez un **test** pour vérifier que la variable existe et n'est pas vide et affichez un message si la condition n'est pas remplie.
- **Sécurisez** la variable
3. Écrivez un fichier `bonjourPost.php` qui contient la structure de base d'un fichier HTML5 valide.
- Affichez le contenu des variables `firstname` et `lastname` du tableau `$_POST` dans le `<body>`
- Testez avec Postman en transmettant 0, 1 ou les 2 variables via la méthode `POST`
- Ajoutez le test d'existence des deux variables et **sécurisez-les**.
4. Écrivez un fichier **HTML** `formulaire.html` qui contient un formulaire demandant à l'utilisateur son nom et son prénom avec des balises `<input>` de type texte. Ce formulaire doit avoir pour **action** le fichier `bonjourPost.php`. Testez avec votre navigateur l'affichage du formulaire et ce qu'il se produit lorsque vous le soumettez.
5. Dans `bonjourPost.php`, ajoutez **en tout début de fichier** un test pour vous assurer que la page est demandée via la méthode POST du protocole HTTP (regardez la doc du tableau [`$_SERVER`](https://www.php.net/manual/fr/reserved.variables.server.php)). Si ce n'est pas le cas, effectuez une demande de redirection vers la page `formulaire.html` (regardez la doc de la directive [`header`](http://php.net/manual/fr/function.header.php)).
Exercice 2 - Générer une liste
------------------------------
1. Écrivez un fichier PHP `liste.php` qui produit un document HTML contenant
**une liste de 10 items** générés en PHP avec une boucle `for`. Testez avec Postman et votre navigateur.
2. Écrivez un fichier PHP `listeGet.php` similaire à `liste.php`, où le
nombre d'items à générer est disponible dans **la variable `nbItems` du tableau `$_GET`**. Testez avec Postman et un navigateur. Pensez à ajouter un test pour vérifier que votre variable est un entier et transtypez-la (cast).
3. Écrivez un fichier PHP `listePost.php` similaire à `liste.php`, où le
nombre d'items à générer est disponible dans **la variable `nbItems` du tableau `$_POST`**. Testez avec Postman.
4. Testez le 3. avec votre navigateur. Pour cela, créez un fichier PHP contenant un **formulaire** avec `listesPost.php` pour action.
Exercice 3 - Compteur de visites en session
-------------------------------------------
1. Écrivez un fichier PHP `counter.php` qui :
- crée ou rétablit une session PHP pour le client
- initialise ou incrémente la variable `$counter` qui sert de compteur
- affiche le nombre de fois que le fichier a été demandé.
Testez avec Postman et le navigateur en appellant plusieurs fois la page `counter.php`. Le chiffre indiqué doit augmenter de 1.
2. Écrivez un fichier PHP `resetCounter.php` qui :
1. réinitialise le compteur présent dans la session
2. effectue une demande de redirection vers le fichier `counter.php` (regardez la doc de la directive [`header`](http://php.net/manual/fr/function.header.php)).
> **Note** : ce script doit contenir exactement 3 instructions.
3. Ajoutez un lien HTML vers le script `resetCounter.php` dans le `<body>` renvoyé par `counter.php`. Testez dans votre navigateur.
4. Dans Postman ou votre navigateur, supprimez le cookie de session `PHPSSID` puis rechargez la page. Que se passe-t-il ?
5. Réalisez un schéma comportant un navigateur, un serveur web et un module PHP. Présentez à l'aide de flèches et de numéros la série de requêtes/réponses qui sont échangées lorsque vous cliquez sur le lien ajouté à la question 3. Pour chaque numéro :
- expliquer brièvement l'objet de la requête/réponse : qui envoie/réceptionne ?
- indiquez le contenu de la requête/réponse : entête, corps, variables, etc.
Exercice 4 - Compteur de visites dans un cookie
-----------------------------------------------
Faites les questions 1 à 3 de l'exercice 3 sans utiliser les sessions mais uniquement un cookie qui contient la variable `counter`.
TP2 - Gestion de comptes utilisateur
====================================
Créez un répertoire `TP2` contenant les 5 fichiers vides suivants :
- `signin.php`
- `authenticate.php`
- `account.php`
- `signout.php`
- `bdd.php`
Objectifs
----------
L'objectif des exercices suivants est de compléter progressivement les fichiers ci-dessus pour mettre en place un **mécanisme d'authentifications d'utilisateurs**. Ils serviront de base pour les TPs sur la POO et les BDD.
Pour tous les exercices du TP :
- **vérifiez** et **sécurisez** les variables que l'utilisateur peut modifier
- envisagez tous les cas de figures possibles (méthodes HTTP) pour accéder à vos pages et **neutralisez** les cas non désirés
- n'oubliez pas de **commiter/pusher régulièrement** votre travail sur le dépôt Git pour vous familiariser avec.
Exercice 1 : Formulaire de connexion
------------------------------------
> Ce fichier ne doit contenir **aucun code PHP** (pour le moment).
Complétez le fichier PHP `signin.php` pour affichez un document HTML avec un formulaire proposant de s'authentifier à l'aide d'un login et d'un mot de passe.
Exercice 2 : Un fichier comme BDD
---------------------------------
> Ce fichier ne doit contenir **aucun code HTML**.
Pour ce TP, la base de donnée des utilisateurs sera stockée dans le fichier `bdd.php` sous la forme d'un tableau `$users` contenant des couples `'login' => 'mot de passe'`.
Créez ce tableau avec quelques utilisateurs de votre imagination.
Exercice 3 : Authentification
-----------------------------
> **Note** : ce fichier ne comportera aucun code HTML.
Complétez le script PHP `authenticate.php` qui traite la requête HTTP POST du formulaire `signin.php` comme suit :
1. Il demande une redirection vers le fichier `signin.php` si la méthode HTTP utilisée n'est pas POST.
2. Il inclut le fichier `bdd.php`.
3. Il vérifie que le tableau `$users` contient le login transmis en POST. Regardez la documentation de [array_key_exists](https://www.php.net/manual/fr/function.array-key-exists.php)
4. Si le login existe, il vérifie que le mot de passe passé en POST correspond au mot de passe du tableau `$users`.
5. Si les mots de passe correspondent :
- une session est créée
- le login est sauvegardé dans le tableau de session
- une demande de redirection vers le fichier `account.php` est envoyée
6. Dans tous les cas d'échec d'authentification, une demande de redirection vers le fichier `signin.php` est envoyée.
Exercice 4 : Mon compte
-----------------------
Complétez le fichier PHP `account.php` pour qu'il se comporte ainsi :
1. Si l'utilisateur ne s'est pas encore authentifié, une demande de redirection vers le fichier `signin.php` est envoyée.
2. Si l'utilisateur est authentifié, ce fichier lui propose un contenu HTML comportant un message de bienvenue personnalisé ainsi qu'un lien de déconnexion vers le fichier PHP `signout.php`
Exercice 5 : Déconnexion
------------------------
Complétez le fichier PHP `signout.php` pour qu'il :
1. efface l'identité de l'utilisateur connecté de la session courante
2. envoie une demande de redirection vers le fichier `signin.php`
Note : Ce fichier doit contenir **exactement** 3 instructions.
Exercice 6 : Messages d'erreur du serveur vers le client
--------------------------------------------------------
Cet exercice propose de mettre en place un système de messages affichés sur la page `signin.php` pour indiquer à l'utilisateur le problème rencontré par le module PHP.
1. Dans le fichier `authenticate.php`, créez une variable de session `message` qui contiendra un texte relatif aux différents cas de figure rencontrés lors de la tentative d'authentification :
- lorsque le login n'existe pas
- lorsque le mot de passe est incorrect
2. Dans le fichier `signin.php`, affichez le contenu de la variable de session `message` dans une balise `<section>`, si cette variable existe et n'est pas vide.
Pour les plus rapides
---------------------
- Niveau 1 : Ajoutez un fichier de style CSS pour mettre en forme votre formulaire.
- Niveau 2 : Utilisez [Bootstrap](https://getbootstrap.com) pour mettre en forme vos différentes pages.
TP3 - Gestion d'utilisateurs et BDD
===================================
Dupliquez votre répertoire `TP2` dans un nouveau répertoire `TP3` dans lequel nous allons modifier progressivement les fichiers.
Objectifs
---------
Cet exercice vous propose de mettre en place une gestion des utilisateurs dans une base de données SQLite.
> **Note** : il est fortement recommandé d'avoir réalisé l'exercice 6 du TP2 afin de transmettre les message d'erreur de PHP au client.
Exercice 1 : Mise en place de la BDD
------------------------------------
1. Créez un fichier vide `tp3.db`.
2. Utilisez `sqlite3` ou `sqlitebrowser` pour créer une table `Users` permettant de stocker les logins et mots de passe des utilisateurs. Réfléchissez bien aux champs et attributs des champs : auto-increment, unique, null, etc.
3. Ajoutez manuellement plusieurs utilisateurs.
Utilisation de `sqlite3` en ligne de commande :
```bash
$ sqlite3 tp3.db
sqlite> CREATE TABLE ... ;
sqlite> INSERT INTO ... ;
sqlite> .exit
```
Exercice 2 : Déclaration de la BDD
----------------------------------
1. Supprimez toutes les instructions du fichier `bdd.php`
2. Créez une variable `$sqliteFile` qui contient le chemin absolu vers `tp3.db` **sur le serveur PHP que vous utilisez** (utiliser [`$_SERVER['DOCUMENT_ROOT']`](https://www.php.net/manual/fr/reserved.variables.server.php)).
3. Ajoutez un test d'existence du fichier (voir [`file_exists`](https://www.php.net/manual/fr/function.file-exists.php)) et si ce n'est pas le cas, propagez une `Exception` qui indique que le fichier de BDD n'existe pas.
4. Créez une variable `$SQL_DSN` qui correspond au paramètre de la construction d'un objet PDO (voir [le cours](http://adrien.krahenbuhl.fr/courses/IUTRS/W31/CM2) et [la documentation PHP](https://www.php.net/manual/fr/book.pdo.php)).
Exercice 3 : Authentification
-----------------------------
Il s'agit de modifier le fichier `authenticate.php` pour remplacer l'utilisation du tableau `$users` par la BDD `tp3.db` en utilisant **PDO**.
1. Créez un objet PDO en utilisant les informations contenues dans `bdd.php`.
2. Construisez et exécutez une **requête préparée** permettant de récupérer le mot de passe de l'utilisateur.
3. Adaptez les vérifications suivantes du TP2 :
- que l'utilisateur existe (i.e. que le résultat contient des données).
- que le mot de passe transmis en POST correspond au mot de passe trouvé dans la BDD.
> **Note** : Toutes les erreurs possibles doivent déclencher une demande de redirection vers `signin.php` et mettre à jour le messages d'erreur de variable de session `message`.
Exercice 4 : Inscription
------------------------
1. Écrivez un nouveau fichier `signup.php` qui propose un formulaire d'inscription pour un nouvel utilisateur (avec mot de passe et confirmation de mot de passe) et le soumet à la page `adduser.php`.
2. Écrivez un nouveau fichier `adduser.php` qui :
- vérifie que la méthode HTTP utilisée est `POST`
- vérifie et sécurise les champs du formulaire de `signup.php`
- vérifie que le mot de passe et sa confirmation sont identiques
- tente d'insérer le nouvel utilisateur avec une **requête préparée** :
- si la requête s'est bien passée, il demande une redirection vers `signin.php`
- sinon il demande une redirection vers `signup.php`
3. Pour plus de navigabilité, ajoutez sur la page `signin.php` un lien vers `signup.php`, et réciproquement.
> **Note** : Si vous avez fait l'exercice 6 du TP2, vous pouvez ajouter les messages d'erreur et de réussite à la variable de session `message`.
Exercice 5 : Mots de passe cryptés
----------------------------------
Actuellement les mots de passe sont codés en clair dans votre base de données. Vous allez mettre en place le chiffrement (et le décryptage) des mots de passe.
> **Note 1** : Ce serait le bon moment pour faire un commit Git de votre 1ère version fonctionnelle de ce TP.
> **Note 2** : Si tout a bien été fait jusque là, les questions 2. et 3. de cet exercice nécessitent de ne changer **qu'une seule ligne** dans chacun des fichiers.
1. Supprimez de votre BDD tous les utilisateurs inscrits, via `sqlite3` ou `sqlitebrowser`.
2. Modifiez le fichier `adduser.php` afin qu'il enregistre le mot de passe chiffré avec la fonction PHP [`password_hash`](http://php.net/manual/fr/function.password-hash.php).
3. Modifiez le fichier `authenticate.php` pour qu'il compare le mot de passe du formulaire avec celui récupéré dans la BDD à l'aide de la fonction [`password_verify`](http://php.net/manual/fr/function.password-verify.php).
Exercice 6 (bonus) : Vérification des mots de passe côté client
---------------------------------------------------------------
En théorie, la vérification de la similarité des deux mots de passe s'effectue aussi côté client, en Javascript, afin de réduire les requêtes inutiles.
1. Dans `signup.php`, écrivez une fonction javascript `checkPassword` qui récupère le contenu des `input` du mot de passe et de sa confirmation et les compare. Utilisez la fonction [`setCustomValidity`](https://developer.mozilla.org/fr/docs/Web/API/HTMLSelectElement/setCustomValidity) pour mettre à jour la validité du champ de confirmation.
2. Faite exécuter la fonction `checkPassword` à chaque saisie d'un nouveau caractère dans le champ de confirmation. Regardez du côté de l'attribut HTML [`oninput`](https://developer.mozilla.org/fr/docs/Web/API/GlobalEventHandlers/oninput).
Pour les plus rapides
---------------------
- Niveau 1 : Mise en place de fonctions utilitaires pour la redirection et la vérification de la méthode HTTP utilisée dans un fichier `helpers.php`. Pensez au typage !
- Niveau 2 : Ajoutez un fichier de style CSS pour mettre en forme votre formulaire.
- Niveau 3 : Utilisez [Bootstrap](https://getbootstrap.com) pour mettre en forme vos différentes pages.
TP4 - Gestion d'utilisateurs et POO
===================================
Dupliquez votre répertoire `TP3` dans un nouveau répertoire `TP4` dans lequel nous allons modifier progressivement les fichiers.
Objectifs
---------
Ce TP propose :
- de mettre en place l'inscription des utilisateurs dans une base de données SQLite,
- de mettre en place le paradigme de POO.
Exercice 1 : Modification du mot de passe
-----------------------------------------
Vous allez ajouter la fonctionnalité de changement de mot de passe avec deux nouveaux fichiers : la vue `formpassword.php` et le contrôleur `changepassword.php`.
1. Créez un nouveau fichier `formpassword.php` contenant un formulaire avec deux champs : un nouveau mot de passe et sa confirmation. Ce formulaire a pour cible `changepassword.php`.
2. Assurez-vous que ce formulaire soit proposé uniquement si l'utilisateur est connecté. Si ce n'est pas le cas, redirigez-le vers `signin.php`.
3. Créez un nouveau fichier `changepassword.php` qui :
- vérifie que l'utilisateur est connecté
- vérifie que la méthode HTTP utilisée est `POST`
- vérifie et sécurise les champs du formulaire de `formpassword.php`
- vérifie que le mot de passe et sa confirmation sont identiques
- tente de changer le mot de passe de l'utilisateur dans la BDD avec une **requête préparée** :
- si la requête s'est bien passée, il demande une redirection vers `account.php`
- Sinon il demande une redirection vers `formpassword.php`.
4. Pour plus de navigabilité, ajoutez un lien vers `formpassword.php` sur la page `account.php`, et réciproquement.
> **Note** : Pensez à mettre à jour la variable de session `message`.
Exercice 2 : Suppression d'un utilisateur
-----------------------------------------
1. Ajoutez un lien vers `deleteuser.php` sur la page `account.php`.
2. Écrivez un nouveau fichier `deleteuser.php` qui :
- vérifie que l'utilisateur est connecté
- tente de supprimer l'utilisateur de la BDD avec une **requête préparée** :
- si la requête s'est bien passée, il supprime la session et demande une redirection vers `signin.php`.
- sinon il demande une redirection vers `account.php`.
> **Note** : Pensez à mettre à jour la variable de session `message`.
Exercice 3 : Passage en POO - Les bases
---------------------------------------
Cet exercice va vous permettre de créer une classe `User` faisant le lien entre votre BDD et le reste de votre code.
1. Créez un répertoire `models`.
2. Déplacer dans `models` le fichier `bdd.php`.
3. Copiez dans `models` le fichier [`MyPDO.php`](corriges/TP4/models/MyPDO.php).
4. Créez dans `models` un fichier `User.php` qui contient la déclaration de la classe `User` avec :
- deux attributs privés pour le login et le mot de passe avec leurs getters/setters
- un attribut privé constant `USER_TABLE` contenant le nom de la table des utilisateurs à utiliser dans les champs `FROM` des requêtes SQL
- un constructeur prenant en paramètre :
- un login
- un mot de passe avec une valeur par défaut `null`
Exercice 4 : Passage en POO - Authentification
----------------------------------------------
1. Dans la classe `User`, écrivez une méthode publique `exists`, sans paramètre, qui effectue les étapes du fichier `authenticate.php` relatives à la BDD, c'est-à-dire :
- faire une requête vers la BDD pour récupérer l'utilisateur dont le login correspond à l'attribut du login de la classe
- déclencher une `Exception` si la requête échoue
- retourner vrai si l'utilisateur existe et que le mot de passe correspond, faux sinon.
**Attention** : pour accéder à l'objet PDO, utilisez la méthode statique `pdo()` de la classe `MyPDO`.
2. Modifiez le fichier `authenticate.php` en remplaçant tout ce qui concerne les requêtes vers la BDD par :
- la création d'un objet `User` à partir des variables récupérées en POST
- l'utilisation de la méthode `exists` pour vérifier si l'utilisateur existe dans la BDD.
> **Note 1** : "Try-catchez" toutes les exceptions pouvant être déclenchées par l'appel à la méthode `exists()`.
> **Note 2** : Utilisez à bon escient l'attribut `USER_TABLE`.
Exercice 5 : Passage en POO - Ajout d'un utilisateur
----------------------------------------------------
1. Dans la classe `User`, écrivez une méthode publique `create`, sans paramètre, qui effectue les étapes du fichier `adduser.php` relatives à la BDD, c'est-à-dire :
- faire une requête vers la BDD pour insérer l'utilisateur `$this`
- déclencher une `Exception` si la requête échoue
2. Modifiez le fichier `adduser.php` en remplaçant tout ce qui concerne les requêtes vers la BDD par :
- la création d'un objet `User` à partir des variables récupérées en POST
- l'utilisation de la méthode `create` pour insérer l'utilisateur dans la BDD.
> **Note** : "Try-catchez" toutes les exceptions pouvant être déclenchées par l'appel à la méthode `create()`.
Exercice 6 : Passage en POO - Changement de mot de passe
--------------------------------------------------------
1. Dans la classe `User`, écrivez une méthode publique `changePassword`, avec un mot de passe en paramètre, qui effectue les étapes du fichier `changepassword.php` relatives à la BDD, c'est-à-dire :
- faire une requête vers la BDD pour mettre à jour le mot de passe de l'utilisateur `$this` avec celui passé en paramètre
- déclenche une `Exception` si la requête échoue
- mettre à jour l'attribut du mot de passe de la classe avec le nouveau mot de passe sinon
2. Modifiez le fichier `changepassword.php` en remplaçant tout ce qui concerne les requêtes vers la BDD par :
- la création d'un objet `User` à partir de son login
- l'utilisation de la méthode `changePassword` pour modifier le mot de passe de l'utilisateur dans la BDD.
> **Note** : "Try-catchez" toutes les exceptions pouvant être déclenchées par l'appel à la méthode `changePassword()`.
Exercice 7 : Passage en POO - Suppression d'un utilisateur
----------------------------------------------------------
1. Dans la classe `User`, écrivez une méthode publique `delete` qui effectue les étapes du fichier `deleteuser.php` relatives à la BDD, c'est-à-dire :
- faire une requête vers la BDD pour supprimer l'utilisateur `$this`
- déclenche une `Exception` si la requête échoue
2. Modifiez le fichier `deleteuser.php` en remplaçant tout ce qui concerne les requêtes vers la BDD par :
- la création d'un objet `User` à partir de son login
- l'utilisation de la méthode `delete` pour supprimer l'utilisateur de la BDD.
> **Note** : "Try-catchez" toutes les exceptions pouvant être déclenchées par l'appel à la méthode `delete()`.
Pour les plus rapides
---------------------
1. Créez une classe `UserException` qui hérite de la classe PHP `Exception` et utilisez-la pour les exceptions déclenchées par les méthodes de la classe `User`. Adaptez en conséquences les `try...catch` des autres fichiers.
2. Modifier l'architecture de votre application pour mettre les fichiers contrôleurs et vues dans des répertoires `controlers` et `views` au même niveau que `models`.
3. Utilisez [Bootstrap](https://getbootstrap.com) pour mettre en forme vos différentes pages.
<?php
session_start();
if ( !isset($_SESSION['user']) )
{
header('Location: signin.php');
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Account</title>
</head>
<body>
<p>
Hello <?= $_SESSION['user']; ?> !<br>
Welcome on your account.
</p>
<p><a href="signout.php">Sign out</a></p>
</body>
</html>
<?php
/******************************************************************************
* Initialisation.
*/
session_start();
unset($_SESSION['message']);
/******************************************************************************
* Traitement des données de la requête
*/
// 1. On vérifie que la méthode HTTP utilisée est bien POST
if ( $_SERVER['REQUEST_METHOD'] != 'POST' )
{
header('Location: signin.php');
exit();
}
// 2. On vérifie que les données attendues existent
if ( !isset($_POST['login'],$_POST['password']) )
{
header('Location: signin.php');
exit();
}
// 3. On sécurise les données reçues
$login = htmlentities($_POST['login']);
$password = htmlentities($_POST['password']);
/******************************************************************************
* Initialisation de l'accès à la BDD
*/
require_once('bdd.php');
/******************************************************************************
* Authentification
*/
// 1. On vérifie que le login existe dans la BDD
if ( !array_key_exists($login, $users) )
{
$_SESSION['message'] = "Wrong login.";
header('Location: signin.php');
exit();
}
// 2. On vérifie que le mot de passe associé au login est correct
if ( $users[$login] !== $password )
{
$_SESSION['message'] = "Wrong password.";
header('Location: signin.php');
exit();
}
// 3. On sauvegarde le login dans la session
$_SESSION['user'] = $login;
// 4. On sollicite une redirection vers la page du compte
header('Location: account.php');
exit();
<?php
// Ce tableau associe un nom d'utilisateur à un mot de passe :
// user => password
$users = [
'a' => 'a',
'adrien' => 'adrien',
'gabriel' => 'gabriel',
'gil' => 'gil',
];
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Signin</title>
</head>
<body>
<h1>Signin</h1>
<form action="authenticate.php" method="post">
<label for="login">Login</label> <input type="text" id="login" name="login" required autofocus>
<label for="password">Password</label> <input type="password" id="password" name="password" required>
<input type="submit" value="Signin">
</form>
<?php if ( isset($_SESSION['message']) && !empty($_SESSION['message']) ) { ?>
<section>
<p><?= $_SESSION['message']; ?></p>
</section>
<?php } ?>
</body>
</html>
<?php
session_start();
session_destroy(); // ou unset($_SESSION['user']);
header('Location: signin.php');
<?php
require_once('bdd.php');
class MyPDO
{
private static ?PDO $_pdo = null;
private function __construct() {}
public static function pdo() : PDO
{
global $SQL_DSN;
if ( self::$_pdo == null )
self::$_pdo = new PDO($SQL_DSN);
return self::$_pdo;
}
}
images/sshGiltab.gif

615 KiB

w31 @ 7eb057c5
Subproject commit 7eb057c579f7d3a50b9f59445498863b4cca5cf5
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment