Cacomania: HTTP session handling with Node.js

Cacomania

HTTP session handling with Node.js

Guido Krömer - 15. November 2012 -

As promised before, I'm going to write another tutorial about Node.js. This is just a little part of the third chat server tutorial. The topic is how to handle sessions with Node.js, because writing a Ajax/JSONP based chat server will make use of sessions.

A single session gets represented by the Session class that is listed below. On instantiation a new session id gets generated which is a random value. This random value gets generated by the getRandom() method, it multiplies the random number with 1e16, rounds the number downward and returns it as base 36 representation (toString(16) would return a hexadecimal number, toString(8) an octal number, toString(10) is the default behavior). The middle part of the session id is the time the session was created as base 36 , too. The cookie value/session id could look like this one: "1rb2rgxwdm7-h9igt6kx-ebo3nwmqzv".

The SessionHandler class manages the sessions, the getSession() method it returns a new or existing session object depending on the clients request. It searches in the request.headers.cookie string for an cookie with the defined cookieName which is 'SESSION' by default. If a session was found in the sessions hashmap this one will returned otherwise a new session will be created and the Set-Cookie field will be added to the response header.

As seen above an interval is used for garbage collecting old sessions which maxAge has expired or having the doDestroy flag set. The interval can be defined by the checkInterval constructor parameter and is one second by default.

Iterating over the sessions are possible using the public forEachSession method, see the example below.

module.exports.ChatServer = function (port, debug) {
    ...
    this.forEachUser = function (callBack) {
        sessionHandler.forEachSession(function(session) {
            if (!session.user) {
                return;
            }
            callBack(session.user);
        });
    }
    ...

This a concrete example using the session handler, the sessionHandler.getSession(request, response) call get a new or existing session. If the query parameter name is set and session.name is not set the parameter gets stored into the session object. Depending the name is defined or not the output generated by the server will be a rude "Who are you?" or "Hello !". Visit the server with "http://localhost:8080/?name=Caco" for setting a name and getting greeted with your name when visiting "http://localhost:8080/" again.

var http = require('http');
var url = require("url");
var SessionHandler = require('./SessionHandler.js').SessionHandler;
var sessionHandler = new SessionHandler();

http.createServer(function (request, response) {
    var query = url.parse(request.url, true).query;
    var session = sessionHandler.getSession(request, response);

    if (!session.name && query.name) {
        session.name = query.name;
    }

    response.writeHead(200, {'Content-Type': 'text/html'});
    if (session.name) {
        response.end('Hello ' + session.name + '!');
    }
    else {
        response.end('Who are you?');
    }
}).listen(8080);

That's all folks!