XCIII. Sessions

Introduction

Le support des sessions de PHP est un moyen de préserver des données entre plusieurs accès. Cela vous permet de créer des applications personnalisées, et d'augmenter l'attractivité de votre site.

Si vous êtes familier avec la gestion de session de la librairie PHPLIB, vous remarquerez que certains concepts sont similaires.

Chaque visiteur accédant à votre page web se voit assigné un identifiant unique, appelé 'identifiant de session'. Il peut être stocké soit dans un cookie, soit propagé dans l'URL.

Le support des sessions vous permet d'enregistrer un nombre illimité de variables qui doivent être préservées entre les requêtes. Lorsqu'un visiteur accède à votre site, PHP va vérifier automatiquement (si session.auto_start est activé1) ou sur demande (explicitement avec session_start() ou implicitement avec session_register()) si il existe une session du même nom. Si c'est le cas, l'environnement précédemment sauvé sera recréé.

Toutes les variables sont sérialisées après l'exécution du script PHP. Les variables qui sont indéfinies sont marquées comme telles. Lors des accès ultérieurs, elles ne seront pas définies, jusqu'à ce que l'utilisateur le fasse.

Note : La gestion des sessions a été ajoutée en PHP 4.0.

Sessions et sécurité

Lien externe : Session fixation

Utiliser les sessions ne signifie pas que les données de session ne pourront être vue que par un seul utilisateur. Il est important de garder cela en tête, lorsque vous stockez et affichez des données importantes. Lors que vous stockez des données dans une session, il faut se demander quels seront les problèmes posés si quelqu'un d'autre accède à cette information, ou comment votre application est affectée si la session est en fait celle d'un autre.

Par exemple, si quelqu'un usurpe une session, il peut alors poster un message dans un forum sous une fausse identitée. Quelle est la gravité de ce problème? Ou bien, il peut accèder aux commandes d'un client, et même, modifier son panier d'achat. A priori, c'est moins problématique pour un fleuriste que pour un pharmacien.

Par conséquent, lorsque vous manipulez des données importantes, il faut exploiter d'autres méthodes pour décider si une session est valide ou pas. Les sessions ne fournissent pas une méthode fiable d'authentification.

Les sessions reposent sur un identifiant de session, ce qui signifie que quelqu'un peut voler cet identifiant, rien qu'en volant l'ID. Ce vol peut être rendu très difficile, comme par exemple en utilisant les cookies, mais en aucun cas cela sera impossible. Les sessions dépendent aussi de la discipline de l'utilisateur qui referme son navigateur à la fin de la session pour tout clore proprement. De plus, même les cookies de session peuvent être surveillés sur un réseau, ou bien notés par un proxy.

Pré-requis

Ces fonctions sont disponibles dans le module PHP standard, qui est toujours accessible.

Installation

Le suport des sessions est activé par défaut. Si vous souhaitez exclure le support des sessions de PHP, vous devez utiliser l'option --disable-session lors de l'exécution du script de configuration. Pour utiliser la mémoire vive pour le stockage des sessions, compilez PHP avec l'option --with-mm[=DIR] .

La version windows de PHP dispose du support automatique de cette extension. Vous n'avez pas à ajouter de librairie supplémentaire pour disposer de ces fonctions.

Configuration à l'exécution

Le comportement de ces fonctions est affecté par la configuration dans le fichier php.ini.

Tableau 1. Options de configuration

NomPar défautModifiable
session.save_path"/tmp"PHP_INI_ALL
session.name"PHPSESSID"PHP_INI_ALL
session.save_handler"files"PHP_INI_ALL
session.auto_start"0"PHP_INI_ALL
session.gc_probability"1"PHP_INI_ALL
session.gc_maxlifetime"1440"PHP_INI_ALL
session.serialize_handler"php"PHP_INI_ALL
session.cookie_lifetime"0"PHP_INI_ALL
session.cookie_path"/"PHP_INI_ALL
session.cookie_domain""PHP_INI_ALL
session.cookie_secure""PHP_INI_ALL
session.use_cookies"1"PHP_INI_ALL
session.use_only_cookies"0"PHP_INI_ALL
session.referer_check""PHP_INI_ALL
session.entropy_file""PHP_INI_ALL
session.entropy_length"0"PHP_INI_ALL
session.cache_limiter"nocache"PHP_INI_ALL
session.cache_expire"180"PHP_INI_ALL
session.use_trans_sid"0"PHP_INI_SYSTEM|PHP_INI_PERDIR
url_rewriter.tags"a=href,area=href,frame=src,input=src,form=fakeentry"PHP_INI_ALL
Pour plus de détails sur les constantes PHP_INI_*, reportez-vous à ini_set().

Voici de détails sur les directives de configuration.

session.save_handler string

Définit le nom du gestionnaire de session, qui est utilisé pour stocker et relire les données de session. Par défaut, c'est le système intégré par fichier : files.

session.save_path string

Définit le chemin qui doit être passé au gestionnaire de sauvegarde. Si vous décidez de choisir le gestionnaire par défaut (par fichier), cet argument sera utilisé comme dossier de sauvegarde des sessions. Par défaut, il vaut /tmp. Si le niveau d'imbrication de session.save_path est supérieur à 2, le nettoyage des sessions obsolètes ne s'opérera pas.

Avertissement

Si vous laissez cette option configurée avec un dossier accessible en lecture à tout le monde, comme par exemple /tmp (par défaut), les autres utilisateurs pourront exploiter ces sessions en obtenant la liste de fichiers dans ce dossier.

Note : Les utilisateurs de Windows doivent changer cette valeur de variable pour que les fonctions de sessions de PHP fonctionnent. Indiquez un chemin de dossier valide, comme par exemple : c:/temp.

session.name string

Spécifie le nom de la session, qui sera utilisé comme nom de cookie. Il ne doit contenir que des caractères alphanumérique. Par défaut, c'est PHPSESSID.

session.auto_start integer

Spécifie si le module de session doit démarrer automatiquement, au début de chaque script PHP. Par défaut, c'est 0 (inactivé).

session.cookie_lifetime integer

Spécifie la durée de vie du cookie en secondes. La valeur de 0 siginifie : "Jusqu'à ce que le navigateur soit éteind". La valeur par défaut est : 0.

session.serialize_handler string

Définit le nom du gestionnaire qui est utilisé pour linéariser/délinéariser les données. Actuellement, un format interne à PHP (nommé php) et WDDX (nommé wddx) sont supportés . WDDX est seulement disponible, si PHP a été compilé avec l'option WDDX. Par défaut, c'est php.

session.gc_probability integer

Specifies the probability that the gc (garbage collection) routine is started on each request in percent. Defaults to 1.

session.gc_maxlifetime integer

Spécifie la durée de vie des données sur le serveur, en nombre de secondes. Après cette durée, les données seront considérées comme obsolètes, et supprimées.

Note : Si vous utilisez le gestionnaire de session par fichier, qui est fourni par défaut votre système doit garder la trace des date de dernier accès aux fichier (atime). La FAT de Windows ne le fait pas, alors vous faudra trouver un autre système pour gérer les sessions qui ont expirées.

session.referer_check integer

Contient une sous-chaîne que vous souhaitez retrouver dans tous les entêtes HTTP Referer. Si cet entêtes a été envoyé par le client, et que la sous-chaîne n'a pas été trouvé, l'identifiant de session sera considéré comme invalide. Par défaut, cette option est la chaÎne vide.

session.entropy_file string

Est un chemin jusqu'à une source externe (un fichier), qui sera utilisée comme source additionnelle d'entropie pour la création de l'identifiant de session. Des exemples valides sont /dev/random et /dev/urandom, qui sont disponibles sur tous les systèmes Unix.

session.entropy_length integer

Spécifie le nombre d'octets qui seront lus dans le fichier défini ci-dessus. Par défaut, il vaut 0, c'est à dire inactif.

session.use_cookies integer

Spécifie si le module utilisera les cookies pour stocker les données de session sur le client. Par défaut, il vaut 1, c'est à dire actif.

session.use_only_cookies integer

Spécifie si le module doit utiliser seulement les cookies pour stocker les identifiants de sessions du coté du navigateur. Par défaut, cette option vaut 0 (inactif, pour compatibilité ascendante). En l'activant, vous éviterez les attaques qui utilisent des identifiants de sessions dans les URL. Cette configuration a été ajoutée en PHP 4.3.0.

session.cookie_path string

Spécifie le chemin utilisé lors de la création du cookie. Par défaut, il vaut /.

session.cookie_domain string

Spécifie le domaine utilisé lors de la création du cookie. Par défaut, il ne vaut rien.

session.cookie_secure boolean

Spécifie que les cookies ne doivent être émis que sur des connexion sécurisée. Par défaut, cette option est à off. Cette option a été ajoutée en PHP 4.0.4. Voir aussi session_get_cookie_params() et session_set_cookie_params().

session.cache_limiter string

Spécifie le type de contrôle de cache utilisé pour les pages avec sessions. Les valeurs possibles sont : none, nocache, private, private_no_expire, public. Par défaut, il vaut nocache.

session.cache_expire integer

Spécifie la durée de vie des données de sessions, en minute. Cette option n'a aucune conséquence sur le contrôle de cache. Par défaut, il vaut 180 (3 heures).

session.use_trans_sid integer

Note : En PHP 4.1.2 ou plus ancient, cette option est activée en utilisant l'option de compilation --enable-trans-sid. Depuis PHP 4.2.0, trans-sid est toujours compilée.

Le système de gestion des sessions par URL pose un risque supplémentaire de sécurité : un utilisateur peut envoyer son URL avec l'identifiant de session par email à un ami, ou bien le mettre dans ses signets. Cela diffusera alors l'identifiant de session.

session.url_rewriter.tags string

Spécifie quels sont les balises HTML qui doivent être réécrites si le support transparent du SID est activé. Par défaut, il vaut a=href,area=href,frame=src,input=src,form=fakeentry.

Les options track_vars et register_globals influencent le comportement des sessions, leur stockage et leur restauration.

Note : Depuis PHP 4.0.3, track_vars est toujours activé.

Types de ressources

Cette extension ne définit aucune ressource.

Constantes Prédefinies

Ces constantes sont définies par cette extension, et ne sont disponibles que si cette extension a été compilée avec PHP, ou bien chargée au moment de l'exécution.

SID (chaîne de caractères)

Constante contenant le nom de la session et l'identifiant en cours, sous la forme "name=ID".

Exemples

Note : Depuis PHP 4.1.0, $_SESSION est disponible comme variable globale, au même titre que $_POST, $_GET, $_REQUEST, etc.. Contrairement à $HTTP_SESSION_VARS, $_SESSION est toujours globale. Par conséquent, vous n'avez pas besoin d'utiliser le mot réservé global avec $_SESSION. Notez que cette documentation a été modifiée pour utiliser $_SESSION. Vous pouvez toujours le remplacer par $HTTP_SESSION_VARS si vous préférez l'ancienne version.

Les clés du tableau $_SESSION sont sujettes aux mêmes limitations que les variables PHP habituelles, c'est à dire qu'elles ne peuvent pas commencer par un nombre, mais commencer par une lettre ou un souligné '_'. Pour plus de détails, reportez vous à la section sur les variables.

Si track_vars est activé et register_globals est désactivé, seuls les éléments du tableau global $_SESSION contiendront les variables enregistrées dans la session. Les variables de sessions relues seront uniquement disponibles dans $_SESSION.

L'utilisation de $_SESSION (ou $HTTP_SESSION_VARS avec PHP 4.0.6 et plus ancien) est recommandé pour une meilleure sécurité et un code plus facilement maintenable. Avec $_SESSION, il n'y a pas besoin d'utiliser les fonctions session_register(), session_unregister() et session_is_registered(). Les variables de sessions sont accessibles comme toute autre variable.

Exemple 1. Enregistrer une variable avec $_SESSION.

<?php
session_start();
// Utilisez $HTTP_SESSION_VARS avec PHP 4.0.6 ou plus ancien
if (!isset($_SESSION['count'])) {
    $_SESSION['compteur'] = 0;
} else {
    $_SESSION['compteur']++;
}
?>

Exemple 2. Retirer une variable de session avec $_SESSION et register_globals inactif.

<?php
session_start();
// Utilisez $HTTP_SESSION_VARS avec PHP 4.0.6 ou plus ancien
unset($_SESSION['compteur']);
?>

Exemple 3. Retirer une variable de session avec $_SESSION et register_globals activé, après l'avoir enregistré avec $_SESSION.

<?php
session_start();
// Avec PHP 4.3 et plus r&eacute;cent, vous pouvez simplement utiliser l'exemple pr&eacute;c&eacute;dent
session_unregister('compteur');
?>

Si register_globals est activé, alors toutes les variables globales peuvent être enregistrées comme variables de session, et toutes les variables de sessions seront reconstituées comme variables globales. Comme PHP doit savoir quels variables globales sont enregistrées comme variables de sessions, l'utilisateur doit enregistrer les variables avec session_register() tandis que $HTTP_SESSION_VARS et $_SESSION ne nécessitent pas session_register().

Attention

Si vous utilisez $HTTP_SESSION_VARS et $_SESSION et désactivez register_globals, n'utilisez pas session_register(), session_is_registered() et session_unregister().

Si vous activez register_globals, session_unregister() doit être utilisé, car les variables de session sont enregistrés comme variables globales lorsque les données de sessions sont relues. Inactiver register_globals est recommandé pour des raisons de sécurité et de performances.

Exemple 4. Enregistrer une variable avec register_globals activé

<?php
if (!session_is_registered('compteur')) {
    session_register("compteur");
    $compteur = 0;
}
else {
    $compteur++;
}
?>

Si register_globals est activé, alors les variables globales et les entrées dans le tableau $_SESSION seront des références sur la même valeur pour les valeurs qui auront été enregistrées avant le démarrage de la session (donc, dans les page précédentes).

De plus, si vous enregistrez une nouvelle variable avec la fonction session_register(), l'entrée dans l'environnement globale et $_SESSION ne fera pas de référence vers la même valeur jusqu'à la prochaine utilisation de session_start() (ceci s'applique à PHP 4.2 est avant seulement). C'est à dire qu'une modification dans les variables globales ne seront pas répercutés dans les entrées de $_SESSION. Il est peu probable que cela ait un impact en pratique, et de plus, cela a été corrigé en PHP 4.3.

Passer l'identifiant de session (session ID)

Il y a deux méthodes de propagation de l'identifiant de session :

  • Cookies

  • Paramèter URL

The session module supports both methods. Cookies are optimal, but since they are not reliable (clients are not bound to accept them), we cannot rely on them. The second method embeds the session id directly into URLs.

Le module de session supporte les deux méthodes. Les cookies sont optimaux, mais comme ils ne sont pas sûrs (tous les internautes ne les acceptent pas), ils ne sont pas fiables. La seconde méthode place l'identifiant de session directement dans les URL.

PHP est capable de faire cela de manière transparente, lorsqu'il est compilé avec l'option --enable-trans-sid. Si vous activez cette option, les URL relatives seront modifiées pour contenir l'identifiant de session automatiquement. Alternativement, vous pouvez utiliser la constante SID, qui est définie, si le client n'a pas envoyé le cookie approprié. SID est soit de la forme session_name=session_id ou une chaîne vide.

Note : L'option arg_separator.output de php.ini vous permet de personnaliser le séparateur d'arguments.

L'exemple suivant vous montre comment enregistrer une variable et comment réaliser un lien correct avec une autre page, avec SID.

Exemple 5. Compter le nombre de hits d'un utilisateur sur une page

<?php
if (!session_is_registered('compteur')) {
    session_register('compteur');
    $compteur = 1;
}
else {
    $compteur++;
}
?>

Bonjour visiteur, vous avez vu cette page <?php echo $compteur; ?> fois.<p>;

Pour continuer, <A HREF="nextpage.php?<?php echo SID?>">cliquez ici</A>.

<?php echo SID?> (ou bien <?=SID?> peut être utilisé si les short_open_tag sont actifs) est nécessaire pour préserver l'identifiant de session dans le cas où l'utilisateur a désactivé les cookies. <? echo SID?> n'est pas nécessaire, si --enable-trans-sid a été activé à la compilation de PHP.

Note : Les URLS non relatives sont considérées comme externes au site, et ne recevront pas le SID, car c'est une fuite d'information vers un autre site (envoi d'informations importantes).

Gestion personnalisée des sessions

Pour implémenter un stockage en base de données, ou toute autre méthode, vous aurez besoin de la fonction session_set_save_handler() pour paramétrer vos propres fonctions de stockage.

Table des matières
session_cache_expire -- Retourne la configuration actuelle du cache expire
session_cache_limiter -- Lit et/ou modifie le limiteur de cache
session_decode -- Décode les données de session
session_destroy -- Détruit une session
session_encode --  Encode les données de session
session_get_cookie_params --  Lit la configuration du cookie de session
session_id -- Let et/ou modifie l'identifiant courant de session
session_is_registered --  Vérifie si une variable est enregistrée dans la session
session_module_name -- Lit et/ou modifie le module de session courant
session_name -- Lit et/ou modifie le nom de la session
session_readonly -- Initialise une session en mode lecture
session_register --  Enregistre une variable dans une session
session_save_path -- Lit et/ou modifie le chemin de sauvegarde des sessions
session_set_cookie_params --  Modifie les paramètres du cookie de session
session_set_save_handler --  Configure les fonctions de stockage de sessions
session_start -- Initialise une session
session_unregister --  Supprime une variable de la session
session_unset --  Détruit toutes les variables de session
session_write_close -- Ecrit les données de session et ferme la session