For your case, first of all, you need to know that the session id is generated by a generating function - generateSessionId(by default). This means the session id(sid cookie) DOES NOT contain any user data, the user data stored on the server-side(MemoryStore by default). So you should get the user session data from the server-side rather than get them from the sid cookie.
The operations like:
req.session.userId = userId;
req.session.name = name;
The userId and name will be stored in MemoryStore on the server-side.
Now, let's get the session data. The value of socket.request.headers.cookie will be a string like this:
sid=s%3AfWB6_hhm39Z7gDKvAYFjwP885iR2NgIY.uT80CXyOKU%2Fa%2FxVSt4MnqylJJ2LAFb%2B770BItu%2FpFxk; io=msngndIn0v4pYk7DAAAU
- we should use cookie.parse(str, options) method to parse string to a JavaScript plain object.
{
sid: 's:fWB6_hhm39Z7gDKvAYFjwP885iR2NgIY.uT80CXyOKU/a/xVSt4MnqylJJ2LAFb+770BItu/pFxk',
io: 'eeOnxhDIiPSE_0gfAAAm'
}
- We should unsign the signed cookie use cookieParser.signedCookie(str, secret) method. Get the unsigned
sid:
fWB6_hhm39Z7gDKvAYFjwP885iR2NgIY
- Since the default server-side session storage is
MemoryStore, you need to initialize it explicitly and call store.get(sid, callback) in the WebSocket connection callback function to get the user session data by sid.
The complete working example:
const session = require('express-session');
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const cookie = require('cookie');
const Allusers = [{ id: 1, name: 'Admin', username: 'admin', password: 'admin' }];
const MemoryStore = new session.MemoryStore();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
session({
store: MemoryStore,
name: 'sid',
resave: false,
saveUninitialized: false,
secret: 'secretCode!',
cookie: {
httpOnly: false,
maxAge: 1000 * 60 * 60 * 24 * 30,
sameSite: true,
},
}),
);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.post('/login', (req, res) => {
const { username, password } = req.body;
console.log(username, password);
if (username && password) {
const user = Allusers.find((user) => user.username === username && user.password === password);
console.log(user);
if (user) {
req.session.userId = user.id;
req.session.name = user.name;
return res.redirect('/');
}
}
res.redirect('/login');
});
io.on('connection', (socket) => {
console.log('a user connected');
const cookieString = socket.request.headers.cookie;
console.log('cookieString:', cookieString);
if (cookieString) {
const cookieParsed = cookie.parse(cookieString);
console.log('cookieParsed:', cookieParsed);
if (cookieParsed.sid) {
const sidParsed = cookieParser.signedCookie(cookieParsed.sid, 'secretCode!');
console.log(sidParsed);
MemoryStore.get(sidParsed, (err, session) => {
if (err) throw err;
console.log('user session data:', JSON.stringify(session));
const { userId, name } = session;
console.log('userId: ', userId);
console.log('name: ', name);
});
}
}
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
You will get the session data userId and name like this:
user session data: {"cookie":{"originalMaxAge":2592000000,"expires":"2021-02-14T08:31:50.959Z","httpOnly":false,"path":"/","sameSite":true},"userId":1,"name":"Admin"}
userId: 1
name: Admin
source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/62407074