Il y a à peine un mois et demi, j'ai traité le même problème et j'ai ensuite écrit un article de blog complet sur ce sujet qui va de pair avec une application de démonstration entièrement fonctionnelle hébergée sur GitHub. La solution repose sur des modules de nœud express-session , cookie-parser et connect-redis pour tout lier. Il vous permet d'accéder et de modifier des sessions à la fois depuis le contexte REST et Sockets, ce qui est très utile.
Les deux parties cruciales sont la configuration du middleware:
app.use(cookieParser(config.sessionSecret));
app.use(session({
store: redisStore,
key: config.sessionCookieKey,
secret: config.sessionSecret,
resave: true,
saveUninitialized: true
}));
... et configuration du serveur SocketIO:
ioServer.use(function (socket, next) {
var parseCookie = cookieParser(config.sessionSecret);
var handshake = socket.request;
parseCookie(handshake, null, function (err, data) {
sessionService.get(handshake, function (err, session) {
if (err)
next(new Error(err.message));
if (!session)
next(new Error("Not authorized"));
handshake.session = session;
next();
});
});
});
Ils vont avec un simple module sessionService que j'ai créé qui vous permet d'effectuer des opérations de base avec des sessions et ce code ressemble à ceci:
var config = require('../config');
var redisClient = null;
var redisStore = null;
var self = module.exports = {
initializeRedis: function (client, store) {
redisClient = client;
redisStore = store;
},
getSessionId: function (handshake) {
return handshake.signedCookies[config.sessionCookieKey];
},
get: function (handshake, callback) {
var sessionId = self.getSessionId(handshake);
self.getSessionBySessionID(sessionId, function (err, session) {
if (err) callback(err);
if (callback != undefined)
callback(null, session);
});
},
getSessionBySessionID: function (sessionId, callback) {
redisStore.load(sessionId, function (err, session) {
if (err) callback(err);
if (callback != undefined)
callback(null, session);
});
},
getUserName: function (handshake, callback) {
self.get(handshake, function (err, session) {
if (err) callback(err);
if (session)
callback(null, session.userName);
else
callback(null);
});
},
updateSession: function (session, callback) {
try {
session.reload(function () {
session.touch().save();
callback(null, session);
});
}
catch (err) {
callback(err);
}
},
setSessionProperty: function (session, propertyName, propertyValue, callback) {
session[propertyName] = propertyValue;
self.updateSession(session, callback);
}
};
Puisqu'il y a plus de code dans l'ensemble que cela (comme l'initialisation des modules, le travail avec les sockets et les appels REST à la fois du côté client et du côté serveur), je ne vais pas coller tout le code ici, vous pouvez le voir sur le GitHub et vous pouvez en faire ce que vous voulez.
{ path: '/', _expires: null, originalMaxAge: null, httpOnly: true, secure: true } }
Mais si j'imprime la session dans mes routes, j'obtiens toutes les variables de session que j'ai configurées (nom d'utilisateur, id, etc.)