Aller au contenu

Programmation PHP/Sessions

Un livre de Wikilivres.


Consultez également ces pages dans d’autres projets Wikimedia :

Article encyclopédique sur Wikipédia.
Définition sur Wiktionnaire.


Comme vous le savez, à la fin d'un script PHP, toutes les variables créées sont détruites et il est impossible d'y accéder depuis un autre script. Alors comment faire pour passer des données entre les pages ?

La réponse : les sessions.

C'est en effet la solution la plus simple pour un webmaster afin de garder des informations sur son visiteur.

[modifier | modifier le wikicode]

Une session est plus ou moins semblable aux cookies HTTP. Les données d'une session sont cependant stockées sur le serveur et non chez le client, ce qui l'empêche de pouvoir les modifier manuellement, comme il peut le faire pour un cookie.

La durée de vie d'une session

[modifier | modifier le wikicode]

Une session est, comme son nom l'indique, une session de navigation. Elle commence donc lors de l'accès à une page les utilisant et se termine à la fermeture du navigateur du client.

Une fois la session terminée, elle est détruite ainsi que toutes les données qu'elle contient. Elle doit donc ne contenir que des données temporaires.

Cependant, la session possède aussi un délai d'expiration. Celui-ci peut être modifié dans la configuration du serveur (directive session.gc_maxlifetime de php.ini), mais vaut généralement une trentaine de minutes. Une fois ce délai dépassé, la session est supprimée.

Comment ça marche ?

[modifier | modifier le wikicode]

Lors de l'accès à une page nécessitant une session, PHP va vérifier si une a déjà été ouverte et la réutiliser ou en créer une nouvelle. Il va donc lui attribuer un identifiant unique et se débrouiller pour que la prochaine page consultée puisse le connaître.

Pour cela, il exploite deux fonctionnalités. Premièrement, si l'utilisation de cookie est possible (le client ne les a pas désactivés), PHP crée un cookie contenant l'identifiant de session. Deuxièmement, si les cookies ne sont pas disponibles, il va réécrire les URL de la page pour inclure cet identifiant dans le lien.

Dans les deux cas, le script ayant besoin d'accéder aux données de la session recevra l'identifiant et sera capable de charger les données qu'elle contient.

Est-ce que c’est sécurisé

[modifier | modifier le wikicode]

Une session est toujours plus sécurisée qu'un cookie puisque le client ne peut pas la modifier manuellement. Un risque subsiste tout de même si l'identifiant de session peut être découvert.

Par exemple, les cookies transitent sur le réseau en clair. Si quelqu’un est capable d'intercepter les communications entre le client et le serveur, il est capable de voir le cookie et de découvrir l'identifiant de session. Il n'aura alors plus qu’à créer un faux cookie et PHP le prendra pour le pauvre internaute s'étant fait voler son cookie. Pour éviter cela, on peut utiliser une connexion cryptée ou configurer le serveur de façon à ce qu’il rende la lecture de ce cookie impossible par JavaScript (Http Only).

Utiliser les sessions

[modifier | modifier le wikicode]

Initialiser une session

[modifier | modifier le wikicode]

Pour pouvoir utiliser la fonctionnalité de session de PHP, il faut lancer le moteur de session en utilisant la fonction session_start().

Cette fonction doit être en mesure d'envoyer des headers HTTP, aucune donnée ne doit donc avoir été transmise au navigateur. Vous pouvez soit placer ce code au tout début de votre script, soit utiliser les fonctions de bufférisation de sortie.

Une session portant un nom personnalisé

[modifier | modifier le wikicode]

Une session porte par défaut le nom "PHPSESSID", c’est lui qui sera utilisé comme nom de cookie ou comme paramètre GET dans les liens... pas très esthétique. Il peut donc vous venir l'envie de changer ce nom.

Pour cela, la fonction session_name() entre en scène.

Début d’un principe
Fin du principe


Ce code va donc charger une session avec l'identifiant provenant du cookie ou du paramètre GET portant le nom nom_de_session.

Noter la position de l'instruction 'session_start()'. Elle doit se trouver AVANT n’importe quel traitement de votre page '.php' .

Changer manuellement l'identifiant de la session

[modifier | modifier le wikicode]

PHP détecte automatiquement l'identifiant à utiliser, cependant, vous pourrez avoir besoin de le changer manuellement, si vous voulez développer un système alternatif pour passer l'identifiant de session entre les pages. Vous pouvez par exemple vous baser sur le hachage (md5() ou sha1()) de l'adresse IP du client pour déterminer l'identifiant de la session. Attention aux proxys et aux internautes dont l'IP change à chaque requête.

Pour définir manuellement l'identifiant de session, la fonction session_id(). Elle prend un paramètre optionnel, qui est le nouvel identifiant de session. Dans tous les cas, la fonction retourne l'identifiant courant de la session.

Exemple
<?php

$identifiant = sha1($_SERVER['REMOTE_ADDR']);
/* Premièrement, nous récupérons l'adresse IP du client,
   puis nous utilisons une fonction de hachage pour
   générer un code valide. En effet, l'identifiant d'une
   session ne peut contenir que des lettres (majuscules
   ou minuscules) et des chiffres. */

$ancien_identifiant = session_id($identifiant);
/* Ensuite, nous modifions manuellement l'identifiant de 
   session en utilisant session_id() et en lui donnant 
   l'identifiant généré plus haut. Comme toujours, la
   fonction retourne l'ancien identifiant, on le place
   dans une variable, au cas où on aurait besoin de le
   réutiliser. */

session_start();
/* On démarre la session, PHP va utiliser le nouvel
   identifiant qu'on lui aura fournis. */


Logo

Dans l'exemple ci-dessus, deux ordinateurs accédant au site par la même adresse IP publique, auront accès à la dernière session ouverte (donc pas forcément la leur).

Lire et écrire des données dans la session

[modifier | modifier le wikicode]

Les données de la session sont très facilement accessibles au travers d'un simple tableau PHP. Depuis PHP 4.1.0, vous pouvez utiliser le tableau super-global $_SESSION. Dans les versions plus anciennes, il s'appelait $HTTP_SESSION_VARS et nécessitait le mot clé global pour y accéder depuis une fonction.

Ces tableaux n'existent qu'une fois la session chargée. Tout ce qui est stocké à l'intérieur est sauvegardé et accessible depuis toutes les pages PHP utilisant les sessions.

Exercice : Une zone d'administration protégée par mot de passe

[modifier | modifier le wikicode]

Dans cet exercice, nous allons fabriquer pas-à-pas une zone d'administration pour votre site web, protégée par un mot de passe. Nous nous occuperons de la partie identification uniquement.

Dans le chapitre précédent, vous avez également créé le même type de script, mais en utilisant un cookie. Nous allons donc adapter le code en utilisant des sessions à la place.

Voici le code du formulaire en HTML, il va afficher une boîte de texte et un bouton "Connexion".

Début d’un principe
Fin du principe


La page de vérification
[modifier | modifier le wikicode]

Le formulaire ci-dessus pointe vers une page nommée verification.php. Cette page va vérifier que le mot de passe est juste et, si c’est le cas, placer un élément dans le tableau de la session pour que la page suivante puisse vérifier que vous êtes bien autorisé à voir la page.

Premièrement, nous devons initialiser la session. Nous laissons PHP choisir le nom.

Début d’un principe
Fin du principe


L'appel à la fonction session_start() a fabriqué le tableau $_SESSION. Pour l'instant celui-ci est vide.

Il faut maintenant vérifier que le mot de passe fourni est le bon. Nous créons ensuite une entrée dans le tableau de la session contenant true (vrai) si le code est le bon. Nous pouvons alors rediriger le navigateur de l'internaute ou afficher un message d'erreur.

Début d’un principe
Fin du principe


Si vous ne comprenez pas la ligne if ($mdp == $_POST['mdp']) {, vous devriez lire (ou relire) le chapitre sur les formulaires.

Pour résumé, le code suivant suffit à l'identification du visiteur :

Début d’un principe
Fin du principe


La page d'administration
[modifier | modifier le wikicode]

Cette page doit se nommer admin.php. Si vous décidez d’utiliser un autre nom, il faudra modifier le script d'identification pour qu’il pointe sur la bonne page.

Comme dans l'autre page, nous devons commencer par initier une session.

Début d’un principe
Fin du principe


Nous avons alors accès au tableau $_SESSION.

Si le visiteur a fourni le bon mot de passe, il existe un élément dans le tableau nommé 'admin' et valant true. Dans le cas contraire, cet élément n'existe pas. Il suffit donc de vérifier sa présence pour savoir si le visiteur est réellement l'administrateur du site. Pour cela, nous utilisons la fonction isset() qui vérifie si la variable (ou l'élément du tableau) existe.

Début d’un principe
Fin du principe


La suite du script n'est plus le sujet de cet exercice, le but est en effet atteint. Vérifier l'identité du visiteur pour lui permettre d'accéder à un espace privé.

Logo

La bonne pratique en terme de sécurité, pour éviter que des attaques puissent énumérer les utilisateurs (avant de chercher leurs mots de passe), et de renvoyer la même erreur 403 si l'utilisateur n'existe pas, ou s'il existe mais que son mot de passe est incorrect.

Fermer une session

[modifier | modifier le wikicode]

De la même façon que d'autre fonctionnalités de PHP, comme les connexions aux bases de données ou un pointeur de fichier, les sessions n'ont pas besoin d’être fermée.

Une fois le script PHP terminé, les données de la session sont automatiquement sauvegardées pour le prochain script.

Cependant, durant toute l'exécution du script, le fichier de la session est verrouillé et aucun autre script ne peut y toucher. Ils doivent donc attendre que le premier arrive à la fin.

Vous pouvez fermer plus rapidement une session en utilisant la fonction session_write_close().

Si vous voulez également détruire la session, vous pouvez utiliser la fonction session_destroy() couplée à la fonction session_unset().