How to access the cookie-based session data of an express app from a socket instance
What do I mean with Sharing Express session data with socket.io?
Well, if I have an express app and a socket.io server instance, both attached to the same http or https server, what I would like, is to be able to get, in socket event handlers, the cookie-based session data from the express app (session data created using a module like express-session).
That is, I would like to be able to do something like…
socket.on("logout", function() { // ... session.user = null; // ... });
… and trust that every Express middleware will be aware of that session data modifcation. I.e. I want req.session altered when the socket handler alters the session data.
socket.io middleware
Starting from socket.io 1.x, we have the concept of middleware too. So, as the docs for io.use() state:
a middleware is a function that gets executed for every incoming Socket and receives as parameter the socket and a function to optionally defer execution to the next registered middleware.
What we can do in order to share session information is to fetch the session data we created for express and make it available on every socket by reusing middleware.
Reusing express middleware in socket.io
The handshake property on every socket
Every socket on the server side, has a handshake property with information about the first steps in the creation of the socket. The handshake property is set up on socket creation, so when you do io.on(“connection”, function(socket){}) , you already have socket.handhsake created in the new socket.
That’s the ideal place to store session data if we want to get it on every event handler we attach to a socket.
Combining express middleware and socket.io middleware
An Express middleware function has this signature:
function(req, res, next) {}
and a socket.io 1.x middleware function has this signature:
function(socket, next) {}
… So, all we have to do is to to create an io.use() compatible function that calls the express session middleware…
var session = require("express-session")({/* ... */});
app.use(session);
var iomiddleware = function(socket, next) { var req = socket.handshake, res = {}; // let the session function act like: // - store req.session in socket.handshake, // - use an empty res object // - call socket.io's next() midleware // when the session middleware is done. session(req, res, function() { next(); }); } io.use(iomiddleware) io.on("connection", function(socket) { });
Show me a module for doing that in a simpler way.
In order for making things simpler, I wrote this module: express-socket.io-session.
You use it by:
// Regular instantiation of express-session var session require("express-session")({ secret: "my-secret", resave: true, saveUninitialized: true }); // Regular use of express-sessions with express app.use(session);
//Share the express session with socket.io io.use(require("express-socket.io-session")(session));
There are a couple of libraries that set up session for socket.io 1.x but they differ from express-socket.io-session in the way they are instantiated.