i'm using this authorization function in my socket.io setup:
io.set('authorization', function (data, accept) {
if (!data.headers.cookie) {
return accept('Session cookie required.', false);
}
data.cookie = require("cookie").parse(data.headers.cookie);
data.cookie = require("connect").utils.parseSignedCookies(data.cookie,"yeah whatever");
data.sessionID = data.cookie['connect.sid'];
sessionStore.get(data.sessionID, function(err, session){
if (err) {
return accept('Error in session store.', false);
} else if (!session) {
return accept('Session not found.', false);
}
// success! we're authenticated with a known session.info.
return accept(null, true);
});
});
then i manipulate the session variables like this:
var addAchievementToUser = function(achievement, sessionID) {
sessionStore.get(sessionID, function(err, session) {
//stuff happens here such as
session.info.username = "whatever";
sessionStore.set(sessionID, session, function () {
});
}
});
};
this works fine and does what i want but sometimes it produces some evil race conditions.
so, how can i rewrite this so that it does not create race conditions? i've looked into the connect middleware to see if it is possible to manipulate only a single key / value pair instead of the whole session object. but it seems that this is not possible since the session needs to be a string:
MemoryStore.prototype.set = function(sid, sess, fn){
var self = this;
process.nextTick(function(){
self.sessions[sid] = JSON.stringify(sess);
fn && fn();
});
};
any ideas?
ok so I started using redis middleware which didn't really help me with the problem. anyway, i basically only edit the session via socket.io (and once when the client first connects), so i figured it'd be the "best" to create a session array which contains all active sessions like this:
io.set('authorization', function (data, accept) {
if (!data.headers.cookie) {
return accept('Session cookie required.', false);
}
data.cookie = require("cookie").parse(data.headers.cookie);
data.cookie = require("connect").utils.parseSignedCookies(data.cookie, "rawr");
data.sessionID = data.cookie['connect.sid'];
sessionStore.get(data.sessionID, function(err, session){
if (err) {
return accept('Error in session store.', false);
} else if (!session) {
return accept('Session not found.', false);
}
// success! we're authenticated with a known session.info.
if (!sessions[data.sessionID]) {
sessions[data.sessionID] = session;
}
return accept(null, true);
});
});
so i never need to use the get session method to edit my session data (only the set method). the good thing is that this way it even works when the same client connects with multiple sockets.