Gestion des sessions

Qu’est-ce qu’un état de session ?

L’état de session correspond aux données capturant l’état courant de l’interaction de l’utilisateur avec les applications telles qu’un site web ou un jeu.

Les applications web établissent généralement une session par utilisateur connecté pendant toute la durée de la connexion. L’état de session permet aux applications de se souvenir de l’identité de l’utilisateur, des données de connexion, des informations de personnalisation, des actions récentes, du panier d’achat et de bien d’autres événements.

Lors de chacune des interactions des utilisateurs, la lecture et l’écriture des données de session doivent se faire sans nuire à la qualité de l’expérience de l’utilisateur. En arrière-plan, l’état de session est constitué de données en cache pour un utilisateur ou application spécifique permettant une réponse rapide aux actions de l’utilisateur. Ceci a pour conséquence que pendant que la session de l’utilisateur est en direct, aucun aller-retour à la base de donnée centrale ne devrait être nécessaire.

La dernière étape dans le cycle de vie de l’état de session est celle où l’utilisateur est déconnecté. Certaines données seront conservées dans la base de données pour une utilisation ultérieure, mais les informations passagères peuvent être mises au rebut une fois la session terminée.

Défis et meilleurs pratiques pour l’état de session

Comprendre les meilleures pratiques d’état est un élément clé pour affecter et résoudre les problèmes communs de session, comme l’isolation, la volatilité et la continuité.

Comme la session est en direct, l’application doit pouvoir écrire vers le stockage de session dans la mémoire et lire à partir de celui-ci. Ceci signifie que les opérations d’écriture sont plus rapides, mais aussi qu’il n’y a pas de tolérance de perte de données. Comme les données de stockage de session ne sont pas une simple capture d’écran d’une autre base de données, elles doivent être hautement durables et toujours disponibles.

L’état de session est similaire à un cache, mais ses cycles de lecture/écriture sont différents : Un cache tolère les pertes de données et peut être récupéré quand vous le désirez à partir d’une base de données primaire. L’écriture dans le cache nécessite l’écriture dans la base de données sous-jacente. L’état de session ne peut en revanche qu’être récupéré qu’à partir de la source de données primaire lorsque la session de l’utilisateur démarre et ne peut être conservé en continu depuis la source qu’à la fin de la session.

L’état de session peut être volatile ou permanent, ce qui signifie que les données peuvent être soit mises au rebut ou conservées de manière persistante sur le stockage sur disque une fois la session de l’utilisateur terminée. Un exemple de session volatile peut être l’historique de navigation dans les pages d’un intranet d’entreprise. Il y a peu d’intérêt à le conserver. Par contre, un panier d’achat dans une application d’e-commerce est critique pour le commerce et doit être enregistré dans un stockage permanent.

L’état de session est enregistré sous forme d’un couple clé-valeur avec l’identifiant de l’utilisateur comme clé et les données de session comme valeur. Ceci garantit que les sessions de l’utilisateur n’accèdent pas aux informations des autres personnes.

Le stockage de l’état de session dans un cache rapide intégré à la mémoire permet des scénarii d’analyse en ligne qui pénaliseraient sinon une base de données transactionnelle. Ces applications incluent une analyse et des tableaux de bord, des moteurs de recommandation et la détection de fraude en temps réel.

Comment Redis Enterprise accélère les choses

Comment utiliser Redis Enterprise pour la gestion de la session

Considérez une application de discussion en ligne utilisant MySQL comme base de données relationnelle, Node.js comme technologie de serveur de sauvegarde et Redis Enterprise pour la gestion de la session. L’accueil comprend deux pages : une page d’accueil proprement dite où l’utilisateur s’enregistre et une page de chat où l’utilisateur tape et envoie des messages.

Pour faire les choses simples, nous ne vous montrerons ici que le code du serveur. Il expliquera comment mettre en œuvre le cycle de vie de l’état de session dans Node.js. Nous omettons également les pages de vue HTML et le reste de l’application.

Tout d’abord, les éléments dépendants des charges d’application, y compris la session, les objets Redis et le client MySQL :

var express = require("express");
var session = require('express-session');
var mysql = require("mysql");
var redis = require("redis");
var redisStore = require('connect-redis')(session);
var redisClient = redis.createClient();
// more dependencies are loaded here...

Les déclarations ci-dessus créent des objets pour la gestion du routage web, la session, la base de données, la mise en cache et les bibliothèques de session Node.js. Configurez alors Redis comme stockage des session :

app.use(session({
secret: 'mysecret',
// create new redis store.
store: new redisStore({ host: 'localhost', port: 6379, client: redisClient }),
saveUninitialized: false,
resave: false
}));

Configurez ensuit les itinéraires express Node.js pour la page d’accueil et de chat avec la prise en charge des requêtes AJAX provenant du client, y compris la connexion, la déconnexion et l’envoi de commentaires.

Lorsqu’un utilisateur demande la page d’accueil, le serveur les redirige à la page chat.html ou affiche la page de connexion login.html, selon que l’utilisateur est connecté ou pas. Le bout de code ci-dessous montre le code du gestionnaire pour l’itinéraire web /get :

app.get('/',function(req,res){
// create new session object.
if(req.session.key) {
// user is already logged in
res.redirect('/chat');
} else {
// no session found, go to login page
res.render("login.html");
}
});

Lorsque l’utilisateur soumet les données du formulaire de connexion (avec l’e-mail et le mot de passe), le client JavaScript AJAX envoie les données du formulaire au serveur. Dans cet exemple, il appelle executeLoginDbCommand fonction (pas montrée ici) qui exécute une requête SQL sur la base de données MySQL et renvoie un objet contenant les données de session de l’utilisateur précédemment enregistrées.

Si la connexion est réussi, les données de l’utilisateur provenant de MySQL sont enregistrées dans la session web sauvegardée par le stockage de session de Redis et le code du client JavaScript redirige l’utilisateur vers la page de chat :

app.post('/login',function(req, res){
// SQL Query will compare login and password
// from HTTP request body to user table data
executeLoginDbCommand(req.body.Email, req.body.Password, function(dbResult){
//
if(!dbResult) {
res.json({"success" : false,"message" : "Login failed ! Please register"});
} else {
req.session.key = dbResult;
res.json({"success" : true,"message" : "Login success."});
}
});
});

La page de chat de l’application lit et publie des messages pour les autres personnes connectées à l’application. Comme les utilisateurs ne voient que leur propres interactions de message avec les autres, les données renvoyées par le serveur pour la page de chat change lorsqu’on change d’utilisateur. Ce qui est plus important est le fait que cette page est réservée aux utilisateurs connectés. La vérification de la clé de session révèle si l’utilisateur est connecté ou pas :

app.get('/chat',function(req,res){
if(req.session.key) {
//user is already logged in,
//so let's render the chat page with the user email
res.render("chat.html",
{
email : req.session.key["UserEmail"],
name : req.session.key["UserName"]
});
} else {
// no session found, go to login page
res.redirect("/");
}
});

Lorsque l’utilisateur soumet un nouveau commentaire à partir de la page du chat, le client JavaScript AJAX envoie les données du formulaire au serveur. Si l’utilisateur est connecté, les commentaires sont insérés dans la table MySQL UserComments. Ceci est réalisé en invoquant la fonction executeSendCommmentDbCommand (pas affichée ici).

app.post("/sendComment",function(req,res){
// This SQL command will insert a new comment in
// users table
if(req.session.key) {
executeSendCommmentDbCommand(req.body.Email, req.body.Recipient, req.body.Comment, function(dbResult){
if(!dbResult) {
res.json({"success" : true, "message" : "Comment has been sent successfully."});
} else {
res.json({"success" : false, "message" : "SendComment failed!"});
}
});
} else {
res.json({"success" : false, "message" : "Please login first."});
}
});

Lorsque l’utilisateur se déconnecte, l’objet de la session est détruit et l’utilisateur est redirigé vers la page de connexion. Mais, au début, executePersistSessionDbCommand (pas affiché ici) enregistre la session d’utilisateur intégrée à la mémoire dans la base de données MySQL :

app.get('/logout',function(req,res){
// user is logged in, so let's destroy the session
// and redirect to login page.
if(req.session.key) {
executePersistSessionDbCommand(req.session, function(dbResult){
if(!dbResult) {
req.session.destroy(function(){
res.redirect('/');
} else {
res.json({"success" : false, "message" : "Session persistence failed!"});
}
});
});
} else {
res.redirect('/');
}
});

Ces bouts de code ne font qu’effleurer la surface d’une application réelle utilisant Redis comme stockage de session. Mais ils montrent comment Redis peut gérer le cycle de vie de l’état de session intégré à la mémoire en combinaison avec le stockage de base de données permanent comme MySQL.


Les prochaines étapes