Http et la conservation d’informations sur les clients

Problème

Le protocole HTTP est un protocole sans mémoire. Une requête d’un client ou les informations qui y sont rattachées ne sont pas mémorisées par défaut.

Plusieurs techniques ont été développées pour remédier à ce manque:

  • Envoyer de l’information sur l’URL

  • Utiliser un champ caché HTML

  • Utiliser des Cookies

  • Utiliser des Sessions

Envoi d’information sur l’URL:

Considérons une première page, page1.php:

<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title> Formulaires</title>
</head>
<body>
<?php
	if (!isset($_GET['login'])){
		?>
	<form method='GET' 
		  action=<?php echo $_SERVER['PHP_SELF'] ?>
	>
	<p>Login: <input type="text" name="login"></p>
	<input type="submit" value="Valider">
	</form>
	<?php
	}
	else {
	header('Location:page2.php?login='.$_GET['login']);
	}
?>
</body>
</html>

qui se poursuit par une page2:

<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Formulaires</title>
</head>
<body>
<?php
	if (isset($_GET['login'])){
		echo $_GET['login'];
	}
	else {
	header('Location:page1.php');
	}
?>
</body>
</html>

Exécution :

Passage d’info sur l’URL

Utiliser des cookies:

L’information est stockée dans un petit fichier texte sur le navigateur du client. On peut par exemple s’en servir pour stocker un identifiant de session, un login, un compteur de visites ou encore mesurer un temps de connexion.

<?php  
if (isset($_COOKIE['compteur']))
  {
    $message = "Vous etes deja venu ".$_COOKIE['compteur']." fois<br/>\n";
    $valeur = $_COOKIE['compteur'] + 1;
  }
  else
  { 
     $message = "Je vous met un petit cookie<br/>\n";
     $valeur = 1;
  } 
setCookie("compteur", $valeur);
echo $message; 

Exécution :

Cookies en PHP

Mais si on a des informations en plus grand nombre à stocker ou qui revètent un caractère plus sensible, on préférera les stocker essentiellement côté serveur et utiliser le mécanisme plus complet des sessions. Celui-ci consiste à utiliser le tableau associatif _SESSION[] qui permet de stocker toute sorte d’informations associées à ce client (données de type nombres ou chaines, tableaux ou objets PHP).

Considérons une première page mettant en place une session:

<?php
// session1.php
session_start();
if (!isset($_SESSION['cpt']))
    $_SESSION['cpt']=0;
else 
    $_SESSION['cpt']++;
echo "Vous avez vu cette page ".$_SESSION['cpt']." fois <br/>\n";
echo "Le SID courant est " . session_id(); 
echo "<br/> <a href=\"session2.php\">Aller à la page suivante session2.php</a>";

Puis on va relire les informations stockées en variables de session dans une autre page:

<?php
// session2.php
session_start();
if (!isset($_SESSION['cpt'])) 
    $_SESSION['cpt']=0;
else 
    $_SESSION['cpt']++;
echo "bonjour {$_SESSION['login']} !<br>\n";
echo "vous avez vu cette page " . $_SESSION['cpt'] . " fois<br/>\n";
echo "Votre SID est toujours " . session_id();
echo "<br/> <a href=\"session1.php\">Retour a session1.php</a>";

Exécution :

Utilisation variable de session PHP

Champs cachés

Un quatrième mécanisme est employé pour conserver de l’information dans des pages Web elles-mêmes comme l’utilisation de champs cachés : input de type hidden. Ces champs peuvent par exemple servir à stocker dans des formulaires HTML un champ spécial dit csrf token qui contiendra un identifiant unique temporaire pour se prémunir des attaques de type CSRF : Cross Site Request Forgery dont un exemple est l’envoi d’un mail contenant une image a quelqu’un et cette image est en fait un lien vers une page d’administration sur laquelle le destinataire du mail a des droits particuliers comme editer ou supprimer une ressource.

Cette page pourra déclencher une suppression ou une modification de contenu non souhaitée.

Les principaux Frameworks Web comme Symfony, Laravel en PHP ou Django, Flask en Python prennent en charge la génération automatique de ce token et sa mise en variable de session mais il faut tout de même l’appeler dans les formulaires ou lors de l’utilisation d’Ajax.