Michael de Silva's Blog

Software Engineer. Rubyist and Roboticist.

Michael de Silva's Blog

Software Engineer. Rubyist and Roboticist.

Cookies and Session Management in NodeJS

Here's a snippet from a recent NodeJS app with Express

app.use(cookieParser());

...

var session_secret = process.env.SESSION_SECRET;
app.use(session({
  secret: session_secret,
  store: new RedisStore({
    port: 6379
  }),
  resave: true,
  saveUninitialized: true
}));

/**
 * Load current user from session.
 */
app.use(function (req, res, next) {
  req.user = req.session.user;

  /**
   * Help troubleshoot cookies
   */
  // if (app.get('env') === 'development') {
  //   console.log('Session ID: ', req.sessionID);
  //   console.log('Cookies: ', req.cookies);
  //   console.log(req.session.cookie);
  // }

  // if (app.get('env') === 'development') {
  //   console.log('Logged in user set as ', req.user);
  // }

  return next();
});

Uncommenting the troubleshooting middleware, yields the following debug info. Notice how the session ID is stored by way as part of the cookie sid. The format used is [sid].[signature].

Session ID:  rKZiUCm_udlh7klVw8jpkS3X2rpZn68T
Cookies:  { 'connect.sid': 's:rKZiUCm_udlh7klVw8jpkS3X2rpZn68T.279rfeYyrnlI4gF9uz2rXoxH4QBK5JZ9ZPK
3rtnnOXw' }
{ path: '/',
  _expires: false,

  originalMaxAge: false,
  httpOnly: true }

However, the cookie itself, does not contain much about the session itself. For this, we need to break out redis-cli for some further digging

127.0.0.1:6379> INFO keyspace
# Keyspace
db0:keys=1,expires=1,avg_ttl=86377798

127.0.0.1:6379> KEYS *
1) "sess:3bTHIYVodfDk7QmTH1IgGbE2qvo3fO9U"

127.0.0.1:6379> GET "sess:3bTHIYVodfDk7QmTH1IgGbE2qvo3fO9U"
"{\"cookie\":{\"originalMaxAge\":false,\"expires\":false,\"httpOnly\":true,\"path\":\"/\"},\"flash\":{},\"passport\":{\"user\":1},\"user\":{\"id\":1,\"email\":\"michael@inertialbox.com\",\"password\":\"$2a$10$/jTo.5N5Ml/sB/XKHhdUOuYWVDWB5PCAjIfFLoiKwUKsUrT5uDuse\",\"mobile\":\"0777123999\",\"created_at\":\"2016-11-30T16:30:15.000Z\"}}"

Interestingly enough, the session is stored as a Redis key with the format sess:[sid] and the value is the JSON.stringify()'ed version of the session contents. Here's the pretty version

{
  "cookie": {
    "originalMaxAge": false,
    "expires": false,
    "httpOnly": true,
    "path": "/"
  },
  "flash": {},
  "passport": {
    "user": 1
  },
  "user": {
    "id": 1,
    "email": "michael@inertialbox.com",
    "password": "$2a$10$/jTo.5N5Ml/sB/XKHhdUOuYWVDWB5PCAjIfFLoiKwUKsUrT5uDuse",
    "mobile": "0777123999",
    "created_at": "2016-11-30T16:30:15.000Z"
  }
}
comments powered by Disqus