Simple Socket.io demo chat app.
This is a simple chat app developed as a personal learning aid following on from the basic chat application in the socket.io tutorial. Also serves as a simple 101 on React but avoids the React "wall of configuration" / "tool chain" bull shit by loading React and Babel in-browser.
In this app, the web manages the login and establishes the session. Only the web can create a valid session and only the web (or indirectly an expiration timer in the session store) can destroy it. But a socket connection know nothing about sessions implicitly, and the WS connection outlive the web session potentially indefinitely. The WS connection should respect the web session, not allowing access unless there is a valid login session. This has to be checked with every packet (just like it has to be checked with every web request).
.-----. .-----.
| Web | <-----------> | API |
'-----' | |
| |
.-----. | |
| WS | <-------> | |
'-----' '-----'
Alt 1: SO suggested a ~trick for using expressjs-session
session middleware with socket.io:
const Session = require('express-session'); // https://github.com/expressjs/session
const session = Session({...})
io.use((socket, next) => session(socket.request, {}, next));
But this doesn't actually seem work. If your Express application uses the session (~any HTTP request) the session that gets attached to the socket request object by the middleware seems to get detached from the actual storage.
Alt 2: Tried calling Session.reload(callback)
with every socket request:
socket.use((packet, next) => {
socket.request.session.reload((err) => {
if(err) next(err);
next();
});
});
But this lead to stack overflow in express-session(!). Trying to use express-session with socket.io may just be the wrong approach.
Alt 3: With session established by express-session we get these cookies on socket.io connection:
connect.sid: s:i77nbbCQOjGbchv2s20EVokAgqNyHr2L.MJGdNuNsPQXxmyHtHC8U6BWMnI2xLuHnKyVHRW24wWA
io: x1VH4cJMfk73GTIxAAAB
"x1VH4cJMfk73GTIxAAAB" is the socket id, "i77nbbCQOjGbchv2s20EVokAgqNyHr2L" is the session id, "MJGdNuNsPQXxmyHtHC8U6BWMnI2xLuHnKyVHRW24wWA" is a cookie signature "connect.sid" is the default name of the session cookie set by expressjs. So it's just a matter of parsing the SID cookie and accessing the session yourself. Express will access the same cookie etc. This works good.
See namespace.clients.