La fumée de cigarette stagnait au plafond. Sur le bureau, deux verres vides. L'un laissait une trace humide, l'autre était sec. Comme les sessions et les cookies. Deux façons de se souvenir. Deux façons de traquer. Les sessions vivaient du côté serveur, éphémères comme la buée sur un miroir. Les cookies du côté client, persistants comme une cicatrice. Dans les deux cas, il s'agissait de reconnaître. D'identifier. De suivre à la trace.
Principe des sessions Une session, c'est un dossier ouvert sur le serveur. Un dossier avec un numéro unique. Quand vous arrivez, on vous donne ce numéro. Vous le montrez à chaque fois. On ouvre le dossier. On y met ce qu'on veut. Quand vous partez, on le ferme. Parfois on le détruit. Parfois il se détruit tout seul, oublié dans un coin.
<?php
// session_demo.php
echo "<div style='font-family: monospace; background: #111; color: #ccc; padding: 20px;'>";
echo "<h3 style='color: #8b0000;'>▪ SESSIONS ▪</h3>";
// Toujours au début, avant tout output
session_start();
// Vérifier si c'est une nouvelle session
if (!isset($_SESSION['premiere_visite'])) {
$_SESSION['premiere_visite'] = date('Y-m-d H:i:s');
echo "<p style='color: #4caf50;'>▪ NOUVELLE SESSION OUVRITE ▪</p>";
}
// Afficher l'ID de session
echo "<p>ID de session : <strong>" . session_id() . "</strong></p>";
echo "<p>Première visite : " . $_SESSION['premiere_visite'] . "</p>";
echo "<p>Nom de la session : " . session_name() . " (PHPSESSID par défaut)</p>";
?>
Création et destruction de sessions Ouvrir. Remplir. Fermer. Parfois brutalement.
<?php
// session_controller.php
session_start();
$action = $_GET['action'] ?? '';
echo "<div style='font-family: monospace; background: #1a1a1a; color: #ccc; padding: 20px;'>";
echo "<h3 style='color: #8b0000;'>▪ CONTRÔLE DE SESSION ▪</h3>";
switch($action) {
case 'create':
// Stocker des données
$_SESSION['agent'] = [
'nom' => 'Marlowe',
'niveau' => 7,
'derniere_action' => date('H:i:s'),
'authentifie' => true
];
$_SESSION['visites'] = ($_SESSION['visites'] ?? 0) + 1;
echo "<p style='color: #4caf50;'>▪ SESSION INITIALISÉE ▪</p>";
echo "<pre style='background: #111; padding: 10px;'>";
print_r($_SESSION);
echo "</pre>";
break;
case 'update':
// Modifier
if (isset($_SESSION['agent'])) {
$_SESSION['agent']['derniere_action'] = date('H:i:s');
$_SESSION['visites']++;
echo "<p style='color: #aaa;'>▪ SESSION MISE À JOUR ▪</p>";
echo "<p>Dernière action : " . $_SESSION['agent']['derniere_action'] . "</p>";
echo "<p>Nombre de visites : " . $_SESSION['visites'] . "</p>";
}
break;
case 'destroy':
// Détruire proprement
$_SESSION = array(); // Vide les données
// Si on veut tuer le cookie de session
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
session_destroy(); // Détruit la session côté serveur
echo "<p style='color: #ff5555;'>▪ SESSION DÉTRUITE ▪</p>";
echo "<p>Cookie de session supprimé, données effacées.</p>";
break;
case 'unset':
// Supprimer une variable spécifique
unset($_SESSION['agent']);
echo "<p style='color: #ffaa00;'>▪ DONNÉES AGENT SUPPRIMÉES ▪</p>";
break;
default:
echo "<p>▪ STATUT DE LA SESSION ▪</p>";
if (empty($_SESSION)) {
echo "<p style='color: #888;'>Session vide ou non initialisée.</p>";
} else {
echo "<pre style='background: #111; padding: 10px;'>";
print_r($_SESSION);
echo "</pre>";
}
}
echo "<hr style='border-color: #444;'>";
echo "<a href='?action=create' style='color: #4caf50; margin-right: 15px;'>▪ INITIER ▪</a>";
echo "<a href='?action=update' style='color: #aaa; margin-right: 15px;'>▪ METTRE À JOUR ▪</a>";
echo "<a href='?action=unset' style='color: #ffaa00; margin-right: 15px;'>▪ EFFACER AGENT ▪</a>";
echo "<a href='?action=destroy' style='color: #ff5555;'>▪ DÉTRUIRE ▪</a>";
echo "</div>";
?>
Utilisation des cookies Les cookies, ce sont les miettes de pain que vous laissez derrière vous. Stockées chez le client. Persistantes. Jusqu'à ce qu'elles expirent ou qu'on les nettoie.
<?php
// cookies_demo.php
echo "<div style='font-family: monospace; background: #111; color: #ccc; padding: 20px;'>";
echo "<h3 style='color: #8b0000;'>▪ COOKIES ▪</h3>";
// Définir un cookie
$expire = time() + (86400 * 30); // 30 jours
setcookie('utilisateur_id', 'agent_47', $expire, "/");
setcookie('preference_theme', 'sombre', $expire, "/");
setcookie('derniere_visite', date('Y-m-d H:i:s'), $expire, "/");
// Cookie sécurisé (HTTPS seulement)
// setcookie('session_secure', 'valeur', $expire, "/", "", true, true);
echo "<p style='color: #4caf50;'>▪ COOKIES DÉFINIS ▪</p>";
// Afficher les cookies existants
echo "<h4>Cookies reçus :</h4>";
if (!empty($_COOKIE)) {
echo "<ul>";
foreach ($_COOKIE as $nom => $valeur) {
echo "<li><strong>$nom</strong> : " . htmlspecialchars($valeur) . "</li>";
}
echo "</ul>";
} else {
echo "<p style='color: #888;'>Aucun cookie reçu.</p>";
}
// Modifier un cookie
if (isset($_GET['modifier'])) {
setcookie('utilisateur_id', 'agent_48', $expire, "/");
echo "<p style='color: #aaa;'>▪ COOKIE MODIFIÉ ▪ Redirection...</p>";
header("Refresh:2; url=cookies_demo.php");
}
// Supprimer un cookie
if (isset($_GET['supprimer'])) {
setcookie('utilisateur_id', '', time() - 3600, "/");
echo "<p style='color: #ff5555;'>▪ COOKIE SUPPRIMÉ ▪ Redirection...</p>";
header("Refresh:2; url=cookies_demo.php");
}
echo "<hr style='border-color: #444;'>";
echo "<a href='?modifier=1' style='color: #aaa; margin-right: 15px;'>▪ MODIFIER L'ID ▪</a>";
echo "<a href='?supprimer=1' style='color: #ff5555;'>▪ SUPPRIMER L'ID ▪</a>";
echo "<div style='margin-top: 20px; background: #1a1a1a; padding: 15px;'>";
echo "<h4>▪ CARACTÉRISTIQUES DES COOKIES ▪</h4>";
echo "<ul style='color: #888;'>";
echo "<li>Stockés côté client (navigateur)</li>";
echo "<li>Limite de taille (~4KB par cookie)</li>";
echo "<li>Limite de nombre par domaine (~50-150 selon navigateur)</li>";
echo "<li>Accessibles via JavaScript (sauf HttpOnly)</li>";
echo "<li>Peuvent être persistants (avec expiration)</li>";
echo "</ul>";
echo "</div>";
echo "</div>";
?>
Cas pratiques (authentification simple) La raison d'être. Reconnaître. Autoriser. Protéger.
<?php
// auth_system.php
session_start();
// Base d'utilisateurs (en vrai, ce serait une base de données)
$utilisateurs = [
'marlowe' => [
'password' => password_hash('code47', PASSWORD_DEFAULT),
'niveau' => 'admin',
'nom_complet' => 'Philip Marlowe'
],
'leopold' => [
'password' => password_hash('serpent', PASSWORD_DEFAULT),
'niveau' => 'user',
'nom_complet' => 'Léopold Stotch'
]
];
// Déconnexion
if (isset($_GET['logout'])) {
session_destroy();
setcookie('remember_token', '', time() - 3600, "/");
header('Location: auth_system.php');
exit();
}
// Si déjà connecté
if (isset($_SESSION['user_id'])) {
header('Location: dashboard.php');
exit();
}
$erreur = '';
// Traitement du formulaire
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
$seSouvenir = isset($_POST['remember']);
if (empty($username) || empty($password)) {
$erreur = "▪ IDENTIFIANTS MANQUANTS ▪";
} elseif (!isset($utilisateurs[$username])) {
$erreur = "▪ UTILISATEUR INCONNU ▪";
} elseif (!password_verify($password, $utilisateurs[$username]['password'])) {
$erreur = "▪ MOT DE PASSE INCORRECT ▪";
} else {
// Authentification réussie
$_SESSION['user_id'] = $username;
$_SESSION['user_data'] = $utilisateurs[$username];
$_SESSION['login_time'] = time();
// Cookie "Se souvenir de moi"
if ($seSouvenir) {
$token = bin2hex(random_bytes(32));
$expire = time() + (86400 * 30); // 30 jours
// En vrai, on stockerait ce token en base de données
setcookie('remember_token', $token, $expire, "/", "", false, true);
// Simuler le stockage
file_put_contents('tokens.txt', "$username:$token\n", FILE_APPEND);
}
// Redirection vers dashboard
header('Location: dashboard.php');
exit();
}
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>▪ Accès Restreint ▪</title>
<style>
body { font-family: 'Courier New', monospace; background: #0a0a0a; color: #aaa; }
.container { max-width: 400px; margin: 50px auto; background: #111; padding: 30px; border: 1px solid #333; }
h2 { color: #8b0000; text-align: center; border-bottom: 1px solid #333; padding-bottom: 10px; }
input[type="text"], input[type="password"] { width: 100%; padding: 10px; margin: 8px 0; background: #222; border: 1px solid #444; color: #ccc; }
button { width: 100%; padding: 12px; background: #8b0000; color: #ccc; border: none; cursor: pointer; font-size: 16px; margin-top: 10px; }
button:hover { background: #a00000; }
.erreur { background: #330000; color: #ff5555; padding: 10px; border-left: 4px solid #ff5555; margin: 15px 0; }
.info { color: #666; font-size: 0.9em; margin-top: 20px; text-align: center; }
.checkbox { margin: 15px 0; color: #888; }
</style>
</head>
<body>
<div class="container">
<h2>▪ IDENTIFICATION ▪</h2>
<?php if ($erreur): ?>
<div class="erreur"><?php echo $erreur; ?></div>
<?php endif; ?>
<form method="POST">
<input type="text" name="username" placeholder="Nom d'agent" required>
<input type="password" name="password" placeholder="Code d'accès" required>
<div class="checkbox">
<input type="checkbox" id="remember" name="remember">
<label for="remember">Maintenir la connexion (30 jours)</label>
</div>
<button type="submit">▪ ACCÉDER ▪</button>
</form>
<div class="info">
Comptes de test :<br>
<strong>marlowe</strong> / <em>code47</em> (admin)<br>
<strong>leopold</strong> / <em>serpent</em> (user)
</div>
</div>
</body>
</html>
<?php
// dashboard.php
session_start();
// Vérification de l'authentification
if (!isset($_SESSION['user_id'])) {
// Vérifier le cookie "remember me"
if (isset($_COOKIE['remember_token'])) {
// En vrai, vérifier le token en base de données
// Pour l'exemple, on simule
$tokens = file('tokens.txt', FILE_IGNORE_NEW_LINES);
foreach ($tokens as $tokenLine) {
list($user, $token) = explode(':', $tokenLine);
if ($_COOKIE['remember_token'] === $token) {
$_SESSION['user_id'] = $user;
break;
}
}
}
// Toujours pas authentifié
if (!isset($_SESSION['user_id'])) {
header('Location: auth_system.php');
exit();
}
}
// Données de session
$user = $_SESSION['user_id'];
$userData = $_SESSION['user_data'];
$loginTime = $_SESSION['login_time'];
$sessionDuration = time() - $loginTime;
// Config session
$sessionTimeout = 1800; // 30 minutes
if ($sessionDuration > $sessionTimeout) {
session_destroy();
header('Location: auth_system.php?expired=1');
exit();
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>▪ Tableau de Bord ▪</title>
<style>
body { font-family: monospace; background: #0a0a0a; color: #ccc; }
.header { background: #111; padding: 20px; border-bottom: 2px solid #8b0000; }
.container { max-width: 800px; margin: 30px auto; }
.card { background: #111; padding: 20px; margin: 20px 0; border-left: 4px solid #8b0000; }
h1 { color: #8b0000; margin: 0; }
.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin: 20px 0; }
.info-item { background: #1a1a1a; padding: 10px; }
.danger { color: #ff5555; }
.success { color: #4caf50; }
a { color: #aaa; text-decoration: none; }
a:hover { color: #8b0000; }
.session-info { font-size: 0.9em; color: #666; }
</style>
</head>
<body>
<div class="header">
<h1>▪ TABLEAU DE BORD ▪</h1>
<div style="float: right;">
<a href="?logout=1" style="color: #ff5555;">▪ DÉCONNEXION ▪</a>
</div>
<div style="clear: both;"></div>
</div>
<div class="container">
<div class="card">
<h2>▪ AGENT CONNECTÉ ▪</h2>
<div class="info-grid">
<div class="info-item">
<strong>Identifiant :</strong><br>
<?php echo htmlspecialchars($user); ?>
</div>
<div class="info-item">
<strong>Nom complet :</strong><br>
<?php echo htmlspecialchars($userData['nom_complet']); ?>
</div>
<div class="info-item">
<strong>Niveau d'accès :</strong><br>
<span class="<?php echo $userData['niveau'] === 'admin' ? 'success' : 'aaa'; ?>">
<?php echo strtoupper($userData['niveau']); ?>
</span>
</div>
<div class="info-item">
<strong>Connecté depuis :</strong><br>
<?php echo gmdate("H:i:s", $sessionDuration); ?>
</div>
</div>
</div>
<div class="card">
<h2>▪ INFORMATIONS DE SESSION ▪</h2>
<div class="session-info">
<p>ID de session : <?php echo session_id(); ?></p>
<p>Cookie de session : <?php echo ini_get('session.name'); ?> = <?php echo $_COOKIE[ini_get('session.name')] ?? 'Non défini'; ?></p>
<p>Durée avant expiration : <?php echo floor(($sessionTimeout - $sessionDuration) / 60); ?> minutes</p>
<p>Données de session :</p>
<pre style="background: #1a1a1a; padding: 10px; overflow: auto;"><?php print_r($_SESSION); ?></pre>
</div>
</div>
<div class="card">
<h2>▪ ACCÈS RAPIDES ▪</h2>
<p><a href="#">▪ ARCHIVES CONFIDENTIELLES ▪</a></p>
<p><a href="#">▪ RAPPORTS D'ACTIVITÉ ▪</a></p>
<p><a href="#">▪ CONTACTS ▪</a></p>
<p class="danger"><a href="?logout=1">▪ EFFACER TOUTES LES TRACES ▪</a></p>
</div>
</div>
</body>
</html>
Je tamponnai la cigarette dans le cendrier. Sessions et cookies. Deux systèmes de mémoire. L'une côté serveur, plus sécurisée mais éphémère. L'autre côté client, persistante mais vulnérable. L'authentification utilisait souvent les deux : une session pour l'accès immédiat, un cookie pour se souvenir. Mais il fallait toujours nettoyer derrière soi. Une session oubliée, un cookie qui traîne, c'était une porte ouverte. Et dans notre métier, les portes ouvertes, on finissait toujours par y trouver quelqu'un qui n'aurait pas dû être là.