Persistance
HTTP est un protocole sans état.
- Les entêtes
Cookie
/Set-Cookie
, introduites par Netscape en 1996, sont le premier mécanisme de maintien d’état pour le Web. - Ce mécanisme reste encore aujourd’hui le plus utilisé.
Exemples d’état
Le server se souvient de l’état du client entre deux requêtes (proches ou distantes dans le temps)
- Remplissage de fourmulaires en plusieurs étapes ;
- Navigation avec authentification (webmail, réseau social, …) ;
- Profil utilisateur ;
- Données dans le cloud ;
- …
Maintenir l’état, c’est dur…
Simuler l’état
HTTP n’a pas de mécanisme natif pour maintenir l’état, mais il peut le simuler :
- Entêtes HTTP
- Authentification HTTP. (Pas courant, difficile à personnaliser).
- Persistance GET/POST
- Identifiants de session, protections CSRF, …
- Cookies, Storage API, IndexedDB
- Persistance assurée par le client.
- Stockage volatile côté server
- Persistance de courte durée : sessions (dépendant du framework), key-value stores (Memcached, Redis, …).
- Stockage persistant côté server
- Persistance de longue durée : système de fichiers, bases de données (SQL, NoSQL, …).
Persistance GET/POST
Passer l’état dans les paramètres de la requête
Exemples
Par la query string
http://.../profile?user=toto
Par l’URL (utilisation du router)
http://.../users/toto/profile
Par le corps de la requête (de type POST)
POST /profile HTTP/1.1
...
user=toto
Persistance GET/POST
Avantages
- Facile à implanter ;
- Robuste : les browsers ne risquent pas de le bloquer ;
- Linkability, Searchability : les données sont lisibles dans l’URL.
Désavantages
- Les liens statiques doivent être générés dynamiquement (facilité par les templates) ;
- Limité à des données de petite taille.
Problèmes potentiels de sécurité
Les données sensibles (mots de passe, etc.) ne doivent pas :
- persister dans ce canaux.
- transiter par l’URL (risques liés au copier-coller, aux caches des proxies, …).
Exemple (méthode GET)
$app->get('/aujourdhui', function(Request $req){
$n = $req->query->get("nom");
return "<p>Bonjour $n, <a href='demain?nom=$n'>à demain</a></p>";
});
$app->get('/demain', function(Request $req){
$n = $req->query->get("nom");
return "<p>Bonjour $n</p>";
});
Cookies
clef-valeur stockés temporairement par le client pour le compte d’un site (domaine).
-
Le server fait la demande avec une entête
Set-Cookie
HTTP/1.1 200 OK ... Set-Cookie: user=toto
-
JavaScript peut aussi demander au browser de stocker un cookie (dépassé par la Storage API)
document.cookie = 'user=toto';
-
Le browser envoye le cookie dans toute requête pour le même domaine
GET /app HTTP/1.1 ... Cookie: user=toto
-
Les cookies sont stockés et envoyés jusqu’à expiration.
Cookies et frameworks
En Silex
use Symfony\Component\HttpFoundation as HTTP;
function handler(HTTP\Request $req) {
$req->cookies->get('user'); // lire les cookies
$res = new HTTP\Response();
$res->headers->setCookie(new HTTP\Cookie('user', 'toto')); // écrire un cookie
$res->headers->clearCookie('user'); // effacer un cookie
}
En Node.js
var cookieParser = require('cookie-parser');
app.use(cookieParser());
function handler(req, res) {
req.cookies.user; // lire les cookies
res.cookie('user', 'toto'); // écrire un cookie
res.clearCookie('user'); // effacer un cookie
}
Storage API
- Stockage clef-valeur, introduit avec HTML5,
- API entièrement côté client (JavaScript),
- Dépasse les limitations des cookies sur la taille des données,
- Garanties sur la durée du stockage.
- Deux interfaces, attachées au domaine :
sessionStorage
: jusqu’à la fermeture du browser,localStorage
: persistant.
if (sessionStorage['user'] === undefined) {
sessionStorage['user'] = 'toto';
}
delete sessionStorage['user'];
Plus d’informations : page du MDN.
Stockage par le client
Utilisations
- Cookies : identifiants de session, compatibilité,
- Storage API : toutes applications, stockage de taille réduite,
- IndexedDB : grandes quantités de données.
Avantages/Désavantages
- Léger pour le serveur, adapté à un site statique.
- Le client peut refuser le stockage.
Problèmes de sécurité potentiels
- Vol de cookies : compromission de session,
- Ne jamais stocker un mot de passe maître chez le client, seulement des mots de passe éphémères (identifiants de session).