Les sessions
Les besoins d'un suivi de session
Les protocoles utilisés sur Internet sont de type connecté ou déconnecté.
Dans le cas des protocoles connectés, comme Telnet et FTP, le client...
- se connecte;
- effectue des transactions avec le serveur;
- se déconnecte.
Ce qui n'est malheureusement pas le cas avec les protocoles déconnectés.
Dans le cas des protocoles déconnectés, une requête (suivie de sa réponse) constitue une transaction simple et isolée.
Pour le serveur, cette requête est indépendante de la précédente et de la suivante.
HTTP est un exemple de protocole déconnecté (on dit aussi "sans état" ou stateless).
À chaque fois qu'un client ouvre une page Web, il obtient une nouvelle connexion au serveur et aucune information à son sujet n'est conservée d'une connexion à l'autre.
Remarque : La version 1.1 de HTTP offre bien des connexions persistantes, mais celles-ci sont limitées dans le temps et cette version du protocole n'est pas supportée par tous les serveurs.
Cette situation est acceptable pour une navigation conventionnelle, mais cause un problème aux applications qui ont besoin de maintenir une "pseudo connexion" entre deux requêtes.
Un bon exemple est le magasinage en ligne : au passage d'une page à l'autre d'un catalogue (deux formulaires situés sur deux pages Web différentes), le serveur a besoin de savoir qu'il s'agit du même client pour être en mesure de gérer correctement son panier d'achats.
Le maintient de cette connexion tout au long d'une série de requêtes s'appelle suivi de session ou contrôle de session.
Principe du suivi de session
Définition :
Une session est un ensemble d'interactions apparentées entre un client unique et un serveur Web sur une période donnée.
Peu importe la technique utilisée, le principe du suivi de session est toujours le même : dans ses réponses, le serveur envoie au client une information que ce dernier retourne dans ses requêtes (cela vous fait-il penser à quelque chose?).
Il existe trois techniques pour faire un suivi de session :
- les champs de formulaire cachés;
- la réécriture d'URL;
- les cookies.
Remarque : Il existe bien sûr une autre solution, rarement utilisée, qui consiste à demander au client de s'identifier à chaque requête.
1- Champ de formulaire caché
Les formulaires HTML peuvent contenir des champs cachés en utilisant des balises input
de type hidden
.
Pour faire un suivi de session avec un champ de formulaire caché, il faut que tous les formulaires envoyés au client contiennent un champ caché contenant son identifiant.
Exemple :
<form action="acheter.php" method="post"> ... <input type="hidden" name="idSession" value="1234"> ... </form>
Le script côté serveur peut récupérer la valeur du champ caché (sous forme de paramètre) et continuer avec le bon panier d'achat :
if (!empty($_POST['idSession'])) { $id = $_POST['idSession']"; // obtention du panier d'achat de ce client $panier = getPanier($id); ... }
L'avantage de cette méthode est qu'elle fonctionne même si les cookies ont été désactivés.
Les deux inconvénients sont que :
- même si l'utilisation d'une requête POST évite l'ajout des paramètres à l'URL (comme c'est le cas avec GET), l'information est quand même visible dans le code source de la page Web;
- côté serveur, il est facile d'oublier d'inclure l'identifiant de session dans le formulaire.
2- Réécriture d'URL
Rappel : le protocole HTTP permet de passer des paramètres dans une requête GET, en les ajoutant au nom de la ressource demandée.
Dans l'exemple suivant, on passe deux paramètres au script PHP :
http://prog101.com/test_hobbit.php?nom=Sam&metier=jardinier
nom = Sam
metier = jardinier
Pour faire un suivi de session avec la réécriture d'URL il faut que tous les hyperliens envoyés au client contiennent en paramètre son identifiant.
Ces informations peuvent permettre au script d'identifier la session à laquelle appartient la requête et de l'associer à des données existantes sur le serveur.
Exemple :
<a href="panier.php?idSession=1234">Voir mon panier</a>
Ce qui va générer l'URL :
http://acheter.com/panier.php?idSsession=1234
L'avantage de cette méthode est qu'elle fonctionne même si les cookies ont été désactivés.
Les deux inconvénients sont que :
- l'information est visible à quiconque peut voir passer l'URL ou consulter l'historique du navigateur;
- côté serveur, il est facile d'oublier d'inclure l'identifiant de session dans un hyperlien.
3- Cookies
Il est possible d'utiliser un cookie pour s'assurer que, d'une requête à l'autre, on a toujours affaire au même client.
Pour cela le cookie contient un identificateur de session (un numéro unique) qui sert d'index dans une structure de données sur le serveur.
Dans cette structure sont stockés les objets associés aux sessions en cours.
Le principe est toujours le même: une information de taille réduite circule entre le client et le serveur, tandis que le plus gros des données de la session est stockée sur le serveur.
C'est la technique utilisée par PHP pour le suivi de session (voir plus loin) avec le cookie PHPSESSID
.
Attention! Nous n'aurons pas à gérer la lecture et l'écriture de ce cookie; PHP le fera pour nous!
L'inconvénient de cette méthode est qu'elle ne fonctionne évidemment pas si l'utilisateur désactive les cookies.
Les sessions en PHP (un exemple)
Vous êtes encouragés à recopier les quatre fichiers suivants et à essayer les scripts.
Fichier page1.php
La première page ne contient pas de code PHP, elle offre seulement un formulaire pour la saisie de la valeur d'une variable qui sera sauvegardée dans la session courante.
Cette variable sera donc accessible à tous les scripts qui partageront cette session.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Page 1</title>
</head>
<body>
<form action="page2.php" method="post">
Entrez votre couleur favorite:
<input type="text" name="paramCouleur">
<br>
<input type="submit">
</form>
</body>
</html>
Sortie :
Fichier page2.php
Ce premier script, appelé via le formulaire de la page précédente, est responsable de l'enregistrement de la variable dans la session courante :
<?php // initialisation de la session session_start(); ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Page 2</title> </head> <body> <?php // récupération d'un paramètre de formulaire et enregistrement dans la session $_SESSION["couleur"] = $_POST["paramCouleur"]; echo 'Votre couleur favorite est le '; echo '<strong>' . $_SESSION["couleur"] . '</strong>'; ?> <p> <a href="page3.php">Page suivante</a> </p> </body> </html>
Sortie :
Mais que fait donc la fonction session_start()?
La fonction session_start()...
- se joint à la session courante;
- en crée une nouvelle si aucune n'est déjà en cours.
Autrement dit, lorsque vous faites appel à session_start()...
-
PHP essaie de lire le contenu d'un cookie nommé par défaut
PHPSESSID
(contient l'identifiant assigné à l'utilisateur); - si ce cookie n'existe pas (pas de session en cours), un nouvel identifiant est créé de manière pseudo-aléatoire, puis est retourné au navigateur dans un cookie sans date d'expiration (effacé à la fermeture du navigateur);
- PHP ouvre alors s'il existe (autrement il le crée) un fichier sur le serveur, qui a comme nom l'identifiant utilisateur;
-
le contenu du fichier est désérialisé et placé dans le tableau des variables de la session appelé
$_SESSION[]
; -
à la fin du script, PHP relit le tableau
$_SESSION[]
et en sérialise le contenu qu'il enregistre ensuite dans le fichier de session sur le serveur.
Fichier page3.php
C'est à partir de ce prochain script que le concept de suivi (ou de contrôle) de session montre toute son utilité.
Ici la variable de session couleur
est accessible, même si elle a été crée dans un autre script!
<?php // restauration de la session existante session_start(); ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Page 3</title> </head> <body> <?php // récupération d'une variable de session echo 'Votre couleur favorite est encore le '; echo '<strong>' . $_SESSION["couleur"] . '</strong><br>'; // suppression d'une variable de session unset($_SESSION["couleur"]); <-- à partir d'ici la variable n'existe plus ?> <p> <a href="page4.php">Page suivante</a> </p> </body> </html>
Sortie :
Fichier page4.php
Dans ce dernier script, on tente d'accéder à une variable qui a été supprimée de la session dans le script précédent :
<?php // restauration de la session existante session_start(); ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>Page 4</title> </head> <body> <?php // tentative d'affichage d'une variable de session supprimée echo 'Votre couleur favorite est encore le '; echo '<strong>' . $_SESSION["couleur"] . '</strong><br>'; // destruction (très) sécuritaire de la session session_destroy(); // supprime le fichier de session session_unset(); // supprime le tableau des variables setcookie("PHPSESSID", null, -1); // supprime le cookie ?> <p> <a href="page1.php">Nouvelle session</a> </p> </body> </html>
Sortie :
Remarque : la destruction de la session comme telle n'est pas obligatoire, puisque le garbage collector détruira le fichier après un certain temps.
On peut aussi utiliser la fonction unset() avec comme paramètre une des variables de la session ou le tableau au complet :
unset($_SESSION["couleur"]); unset($_SESSION); // à la place de session_unset()
Questions et exercices
Question 1
Au niveau du protocole HTTP, après chaque requête au serveur pour l'obtention d'une page Web, le serveur envoie sa réponse et...
Mais que fait-il donc après? Ferme la connexion? La garde ouverte? Si oui jusqu'à quand?
Question 2
Expliquez en vos propres mots pourquoi le suivi de session est nécessaire et permet de contourner les limites du protocole HTTP.
Question 3
Vrai ou faux? Le principe du suivi de session est exclusif au langage PHP.
Question 4
Qu'arrive-t-il d'une session en cours si on ferme le navigateur?
Question 5
Donnez le code HTML d'un formulaire contenant un champ caché et le code PHP pour récupérer sa valeur.
Question 6
Vrai ou faux? L'URL suivante a été générée pas une requête POST.
http://prog101.com/test_hobbit.php?nom=Frodon&race=Hobbit
Question 7
Donnez les trois méthodes possibles pour implémenter le suivi de session. Laquelle de ces méthodes est massivement utilisée?
Question 8
Vrai ou faux? Quand le suivi de session utilise un cookie, l'ensemble des données (ex : panier d'achats) est contenu dans le cookie.
Question 9
Donnez le nom par défaut du cookie de session PHP.
Question 10
Complétez l'énoncé suivant : "Selon les circonstances, la méthode session_start() crée une nouvelle session ou...".
Question 11
Le tableau $_SESSION est de type
a) indexé numériquementb) associatif
Question 12
Vrai ou faux? Effacer tous les cookies dans mon navigateur mettra fin à la session en cours.
Question 13
Vrai ou faux? À chaque fois qu'une nouvelle session est ouverte, un fichier est créé sur le serveur.
Question 14
Expliquez en vos propres mots comment fonctionne le suivi de session. Ça va peut-être vous prendre deux minutes, mais il ne s'agit pas de temps perdu.
Question 15
Quel est le rapport entre le fichier de session sur le serveur et le tableau $_SESSION?
Question 16
Donnez la bonne façon de supprimer la variable $_SESSION['foobar'].
Question 17
On dit que la fonction session_destroy() supprime la session. Mais que fait rigoureusement cette fonction?