Les sessions

Rechercher

Les sessions

  • Par Emacs
  • 11 commentaires
  • 60239 lectures
  • RSS -  Atom

Depuis PHP4, on entend beaucoup parler de sessions. De nombreuses personnes utilisant PHP ignorent encore ce qu'elles sont et à quoi elles servent. D'autres, en revanche, ne savent pas les utiliser à bon escient. Ce tutoriel est une approche à la fois théorique et pratique des sessions. Elles seront présentées au moyen d'un exemple simple tout au long de ce cours. Il s'agit d'un espace de site sécurisé par authentification.

Une session c'est quoi ?

Une session est un mécanisme technique permettant de sauvegarder temporairement sur le serveur des informations relatives à un internaute. Ce système a notamment été inventé pour palier au fait que le protocole HTTP agit en mode non connecté. A chaque ouverture de nouvelle session, l'internaute se voit attribué un identifiant de session. Cet identifiant peut-être transmis soit en GET (PHPSESSID ajouté à la fin de l'url), POST ou Cookie (cookie sur poste client) selon la configuration du serveur. Les informations seront quant à elles transférées de page en page par le serveur et non par le client. Ainsi, la sécurité et l'intégrité des données s'en voient améliorées ainsi que leur disponibilité tout au long de la session. Une session peut contenir tout type de données : nombre, chaîne de caractères et même un tableau.

Contrairement à une base de données ou un système de fichiers, la session conserve les informations pendant quelques minutes. Cette durée dépend de la configuration du serveur mais est généralement fixée à 24 minutes par défaut. Le serveur crée des fichiers stockés dans un repertoire particulier.

Les sessions sont particulièrement utilisées pour ce type d'applications :

  • Les espaces membres et accès sécurisés avec authentification.
  • Gestion d'un caddie sur un site de vente en ligne.
  • Formulaires éclatés sur plusieurs pages.
  • Stockage d'informations relatives à la navigation de l'utilisateur (thème préféré, langues...).

La théorie, c'est bien beau mais en pratique comment ça se passe ? La partie suivante explique l'initialisation et la restauration d'une session ouverte.

Initialisation (et restauration) d'une session

PHP introduit nativement une unique fonction permettant de démarrer ou de continuer une session. Il s'agit de session_start(). Cette fonction ne prend pas de paramètre et renvoit toujours true. Elle vérifie l'état de la session courante. Si elle est inexistante, alors le serveur la crée sinon il la poursuit.

Initialisation et restauration d'une session
<?php
?>

Dans le cas d'une utilisation des sessions avec les cookies, la fonction session_start() doit obligatoirement être appellée avant tout envoi au navigateur sous peine de voir afficher les fameuses erreurs :

"Cannot modify header information - headers already sent by ..." ou "Cannot send session cookie - headers already sent by ...". Cela est du au fait que PHP ne peut plus envoyer de cookie à l'utilisateur car il y'a déjà eu une sortie au navigateur (echo(), print(), espace blanc, tag html...).

Note : il faut appeller session_start() sur chaque page utilisant le système de session.

Lecture et ecriture d'une session

Le tableau $_SESSION

Lorsqu'une session est créée, elle est par défaut vide. Elle n'a donc aucun intérêt. Il faut donc lui attribuer des valeurs à sauvegarder temporairement. Pour cela, le langage PHP met en place le tableau superglobal $_SESSION. Le terme superglobal signifie que le tabeau a une visibilité maximale dans les scripts. C'est à dire que l'on peut y faire référence de manière globale comme locale dans une fonction utilisateur sans avoir à le passer en paramètre. Le tableau $_SESSION peut-être indexé numériquement mais aussi associativement. En règle générale, on préfère la seconde afin de pouvoir donner des noms de variables de session clairs et porteurs de sens.

L'écriture de session

Pour enregistrer une nouvelle variable de session, c'est tout simple. Il suffit juste d'ajouter un couple clé / valeur au tableau $_SESSION comme l'illustre l'exemple suivant.

Déclaration et initialisation d'une variable une session
<?php
// Démarrage ou restauration de la session
// Ecriture d'une nouvelle valeur dans le tableau de session
$_SESSION['login'] = 'Dupond';
?>

Le tableau $_SESSION, qui était vide jusqu'à présent, s'est agrandit dynamiquement et contient maintenant une valeur (Dupond) à la clé associative login. Une variable de session est alors créée.

Note de rappel : à place de la chaîne de caractères « Dupond », nous aurions pu mettre un nombre, un booléen ou encore un tableau par exemple.

Lecture d'une variable de session

Après l'écriture, c'est au tour de la lecture. Il n'y a rien de plus simple. Pour lire la valeur d'une variable de session, il faut tout simplement appeler le tableau de session avec la clé concernée. L'exemple ci-dessous illustre tout ça.

Lecture d'une variable de session
<?php
// Démarrage ou restauration de la session
// Lecture d'une valeur du tableau de session
echo $_SESSION['login'];
?>

Cette instruction aura pour effet d'afficher à l'écran la chaîne de caractères Dupond.

Destruction d'une session

Comme cela a été évoqué plus haut, le serveur détruit lui même la session au bout d'un certain temps si la session n'a pas été renouvellée. En revanche, il est possible de forcer sa destruction au moyen de la fonction session_destroy(). Cela permet par exemple aux webmasters de proposer une page de déconnexion aux membres loggués à leur espace personnel. Cependant, l'utilisation de session_destroy() seule n'est pas très "propre". Le code suivant présente une manière plus correcte de mettre fin à une session.

Destruction propre et complète d'une session
<?php
// Démarrage ou restauration de la session
// Réinitialisation du tableau de session
// On le vide intégralement
$_SESSION = array();
// Destruction de la session
// Destruction du tableau de session
unset($_SESSION);
?>

Pour être convaincu de la destruction de la session, il suffit juste d'essayer d'afficher le contenu du tableau de session au moyen de la fonction print_r().

Configuration des sessions sur le serveur

Une session ne reste ouverte que pendant un certain temps. Tout au plus ce sera celle indiquée par la directive session.gc_maxlifetime du php.ini, entre deux clics consécutifs du client. Il est recommandé de ne pas augmenter la valeur inscrite par défaut. Mais pourquoi ? Tout simplement parceque si la session à une durée de vie plus importante, on s'expose à des risques de piratage par vol de session notamment (cf: voir les liens annexes en fin de tutoriel pour plus d'informations).

Pour les mêmes raisons de sécurité, il est conseillé de configurer le serveur de la façon suivante :

Configuration de PHP recommandée pour les sessions
session.use_cookies 1
session.use_only_cookies 1
session.use_trans_sid 0

Cette configuration implique néanmoins une restriction totale pour les personnes n'acceptant pas les cookies. Ci-dessous, la signification dans le même ordre des 3 lignes de configuration précédentes.

  • L'identifiant de session est transmis par un cookie.
  • Seul le cookie peut transmettre l'identifiant de session.
  • Le PHPSESSID transmis dans l'url est strictement refusé.

Approche pratique : concevoir un accès restreint

Présentation du cas pratique

Le présent chapitre introduit un cas concret d'utilisation des sessions. Il s'agit d'un accès restreint basique. Seul un utilisateur n'est autorisé à être loggué mais cet exemple est à la base de la création d'un espace membre. C'est exactement la même chose. Pour réaliser tout ça, nous aurons besoin de 2 fichiers : le formulaire accompagné de son script de login, et la page protégée. Commençons par le formulaire de login. Le code étant commenté, il n'y aura pas plus d'explications.

Formulaire d'authentification : authentification.php

Cas pratique : formulaire d'identification à un espace membre
<?php
// Definition des constantes et variables
define('LOGIN','toto');
define('PASSWORD','tata');
$errorMessage = '';
// Test de l'envoi du formulaire
if(!empty($_POST))
{
// Les identifiants sont transmis ?
if(!empty($_POST['login']) && !empty($_POST['password']))
{
// Sont-ils les mêmes que les constantes ?
if($_POST['login'] !== LOGIN)
{
$errorMessage = 'Mauvais login !';
}
elseif($_POST['password'] !== PASSWORD)
{
$errorMessage = 'Mauvais password !';
}
else
{
// On ouvre la session
// On enregistre le login en session
$_SESSION['login'] = LOGIN;
// On redirige vers le fichier admin.php
header('Location: http://www.monsite.com/admin.php');
exit();
}
}
else
{
$errorMessage = 'Veuillez inscrire vos identifiants svp !';
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<title>Formulaire d'authentification</title>
</head>
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
<fieldset>
<legend>Identifiez-vous</legend>
<?php
// Rencontre-t-on une erreur ?
if(!empty($errorMessage))
{
echo '<p>', htmlspecialchars($errorMessage) ,'</p>';
}
?>
<p>
<label for="login">Login :</label>
<input type="text" name="login" id="login" value="" />
</p>
<label for="password">Password :</label>
<input type="password" name="password" id="password" value="" />
<input type="submit" name="submit" value="Se logguer" />
</p>
</fieldset>
</form>
</body>
</html>

Exemple de page protégée : admin.php

Exemple de page sécurisée avec les sessions
<?php
// On prolonge la session
// On teste si la variable de session existe et contient une valeur
if(empty($_SESSION['login']))
{
// Si inexistante ou nulle, on redirige vers le formulaire de login
header('Location: http://www.monsite.com/authentification.php');
exit();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<title>Administration</title>
</head>
<?php
// Ici on est bien loggué, on affiche un message
echo 'Bienvenue ', $_SESSION['login'];
?>
</body>
</html>

Petite explication : pour protéger chacune des pages de l'administration, il faut absolument ajouter en tête de fichier le premier script entièrement. Celui-ci redirige instantanément l'utilisateur s'il n'est pas convenablement loggué. Sinon il affiche la page Web.

Liens annexes

Voici une serie de liens pour obtenir un complément d'information sur l'utilisation des sessions.

Conclusion

Le tutoriel s'achève sur ces références. Nous vous recommandons vivement de jeter un oeil à la documentation de PHP au sujet des sessions pour regarder du côté des autres fonctions existantes non évoquées ici. Ceci n'était que le fondement théorique des sessions basé sur un exemple concret et pratique. Vous serez à présent en mesure de construire vos propres applications web à partir de sessions.



Les commentaires

1. Par saturn2 le 29/12/2007 01:48

Bon clair et précis. Mais je pense que je vais allez faire un tour dans les liens annexes pour étoffer un peu tout cela !!

2. Par FranzOnBSD le 08/02/2008 17:54

Merci Emacs pour ce tutoriel. Très clair et très précis, et surtout très bien illustré, ce qui est le plus important pour les jeunes.

3. Par algeo le 15/02/2008 14:48

je ne comprend toujours pas une chose avec les sessions. est ce qu'il faut que l'utilisateur accepte les cookies ou cela n'est pas obligatoire.

4. Par Emacs le 15/02/2008 15:45

Oui ou non ! Tout dépend de la configuration des sessions sur ton serveur Web. Si tu as configuré les sessions pour que l'identifiant de session soit propagé dans un cookie, alors oui l'utilisateur doit accepter les cookies. Si tu configures les sessions pour que l'identifiant de session transite dans l'url en clair, alors non les cookies ne sont pas nécessaire. Le problème avec les identifiants de session dans l'url, c'est que c'est beaucoup plus facilement hackable que lorsque le cookie est propagé chez le client dans un cookie. Il faut toujours transporté l'identifiant de session dans un cookie et refuser strictement la transmission de l'identifiant par l'url. Après si ton client n'accepte pas les cookies, tant pis pour lui...

5. Par Milka le 23/07/2008 15:15

Merci pour ce tutoriel instructif. Il est clair et précis, ce qui me fixe les idées et m'aide à comprendre de manière exacte les sessions !

6. Par Emacs le 23/07/2008 19:34

Merci beaucoup Milka

7. Par nko44 le 11/03/2009 16:41

Bonjour et merci pour ce tutoriel très instructif.
J'ai néanmoins une question (de néophyte) : n'est-il pas risqué de véhiculer un login et un password dans des constantes comme il semble que ce soit le cas dans l'exemple ?
Ne vaudrait-il pas mieux les stocker dans une BDD et interroger cette BDD à chaque validation de formulaire d'authentification ?

8. Par Emacs le 12/03/2009 00:06

@nko44 : il n'y a aucun risque puisque les constantes se trouvent dans le fichier PHP. Elles n'apparaîtront jamais au client. En quoi penses-tu que cela peut être moins sécurisé qu'une base de données ?

9. Par philipsnet le 06/04/2009 17:49

merci je vais essayer mais en cas de problème je vais vous contacter encore

10. Par Abdel le 25/04/2009 20:32

super tuto Merci, je voulu juste savoir pourquoi htmlspecialchars alors que le PHP_SELF il va retourné le nom de script sans une balise html
Merci une autre fois pour votre travail

11. Par Voitures le 18/07/2009 17:34

J'avoue que j'ai déjà lu pas mal de tutoriel sur les sessions, j'ai vu des exemples et j'ai même testé quelques uns, mais j'avais toujours du mal à les exploiter comme je le souhaitais... Maintenant ce n'est plus le cas, grâce à ce tutoriel que je trouve assez claire, simple et très complet.
Un grand merci pour toi Emacs