Is there a simple way to share session data stored in Redis between Rails and Node.js application?

I have a Rails 3.2 application that uses Redis as it's session store. Now I'm about to write a part of new functionality in Node.js, and I want to be able to share session information between the two apps.

What I can do manually is read the _session_id cookie, and then read from a Redis key named rack:session:session_id, but this looks kind of like a hack-ish solution.

Is there a better way to share sessions between Node.js and Rails?

I have done this but it does require making your own forks of things

Firstly you need to make the session key the same name. That's the easiest job.

Next I created a fork of the redis-store gem and modified where the marshalling. I need to talk json on both sides because finding a ruby style marshal module for javascript is not easy. The file where I alter marshalling

I also needed to replace the session middleware portion of connect. The hash that is created is very specific and doesn't match the one rails creates. I will need to leave this to you to work out because there might be a nicer way. I could have forked connect but instead I extracted a copy of connect > middleware > session out and required my own in.

You'll notice how the original adds in a base variable which aren't present in the rails version. Plus you need to handle the case when rails has created a session instead of node, that is what the generateCookie function does.

/***** ORIGINAL *****/
// session hashing function
store.hash = function(req, base) {
  return crypto
    .createHmac('sha256', secret)
    .update(base + fingerprint(req))
    .digest('base64')
    .replace(/=*$/, '');
};

// generates the new session
store.generate = function(req){
  var base = utils.uid(24);
  var sessionID = base + '.' + store.hash(req, base);
  req.sessionID = sessionID;
  req.session = new Session(req);
  req.session.cookie = new Cookie(cookie);
};

/***** MODIFIED *****/
// session hashing function
store.hash = function(req, base) {
  return crypto
    .createHmac('sha1', secret)
    .update(base)
    .digest('base64')
    .replace(/=*$/, '');
};

// generates the new session
store.generate = function(req){
  var base = utils.uid(24);
  var sessionID = store.hash(req, base);
  req.sessionID = sessionID;
  req.session = new Session(req);
  req.session.cookie = new Cookie(cookie);
};

// generate a new cookie for a pre-existing session from rails without session.cookie
// it must not be a Cookie object (it breaks the merging of cookies)
store.generateCookie = function(sess){
  newBlankCookie = new Cookie(cookie);
  sess.cookie = newBlankCookie.toJSON();
};

//... at the end of the session.js file
  // populate req.session
  } else {
    if ('undefined' == typeof sess.cookie) store.generateCookie(sess);
    store.createSession(req, sess);
    next();
  }

I hope this works for you. It took me quite a bit of digging around to make them talk the same.

I found an issue as well with flash messages being stored in json. Hopefully you don't find that one. Flash messages have a special object structure that json blows away when serializing. When the flash message is restored from the session you might not have a proper flash object. I needed to patch for this too.

This may be completely unhelpful if you're not planning on using this, but all of my session experience with node is through using Connect. You could use the connect session middlewhere and change the key id:

http://www.senchalabs.org/connect/session.html#session

and use this module to use redis as your session store:

https://github.com/visionmedia/connect-redis

I've never setup something like what your describing though, there may be some necessary hacking.