Développement d'applications Web avec LAMP

Document d'accompagnement pour le cours 420-KB9-LG

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...

  1. se connecte;
  2. effectue des transactions avec le serveur;
  3. 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.

Le serveur Web répond et ferme immédiatement la connexion.

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 :

  1. les champs de formulaire cachés;
  2. la réécriture d'URL;
  3. 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  :

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 :

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 :

page1.php

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 :

page2.php

Mais que fait donc la fonction session_start()?

La fonction session_start()...

Autrement dit, lorsque vous faites appel à session_start()...

  1. PHP essaie de lire le contenu d'un cookie nommé par défaut PHPSESSID (contient l'identifiant assigné à l'utilisateur);

  2. 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);

  3. PHP ouvre alors s'il existe (autrement il le crée) un fichier sur le serveur, qui a comme nom l'identifiant utilisateur;

  4. le contenu du fichier est désérialisé et placé dans le tableau des variables de la session appelé $_SESSION[];

  5. à 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.

Un cookie de session PHP examiné dans Firefox

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 :

page3.php

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 :

page4.php

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()
Il ne vous aime pas.

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ériquement
b) 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?