I was using express v3.0.0, sockek.io, and redis. Something weird happened when a user without authorization request a connection. The line console.log( 'Error!!!'); was run and the connection should be rejected by the next line return accept(err, false);. However, the connection was still established, and the line socket.log.info('A socket with sessionID', hs.sessionID, 'connected'); was run.
io = socketIO.listen(server);
io.configure(function () {
io.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
data.cookie = parseSignedCookies(cookie.parse(decodeURIComponent(data.headers.cookie)), 'secret');
data.sessionID = data.cookie['connect.sid'];
// save the session store to the data object
// (as required by the Session constructor)
data.sessionStore = sessionStore;
sessionStore.get(data.sessionID, function (err, session) {
if (session) {
req = {
sessionStore: sessionStore
, sessionID: data.sessionID
};
session = new express.session.Session(req, session);
}
if (err || !session) {
console.log( 'Error!!!');
return accept(err, false);
} else {
// create a session object, passing data as request and our
// just acquired session data
data.session = new Session(data, session);
return accept(null, true);
}
});
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted', false);
}
// accept the incoming connection
accept(null, true);
});
});
io.sockets.on('connection', function (socket) {
var hs = socket.handshake;
socket.log.info('A socket with sessionID', hs.sessionID, 'connected');
// setup an inteval that will keep our session fresh
var intervalID = setInterval(function () {
// reload the session (just in case something changed,
// we don't want to override anything, but the age)
// reloading will also ensure we keep an up2date copy
// of the session with our connection.
hs.session.reload( function () {
// "touch" it (resetting maxAge and lastAccess)
// and save it back again.
hs.session.touch().save();
});
}, 60 * 1000);
socket.on('disconnect', function () {
socket.log.info('A socket with sessionID', hs.sessionID, 'disconnected');
// clear the socket interval to stop refreshing the session
clearInterval(intervalID);
});
});
The problem is in the last line of your authorization method:
because
works asynchronous. You MUST NOT return any values from within the authorization function directly but only from the sessionStore.get callback function.
The complete code should be: