Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Connect signed cookie parsing falsy

Connect signed cookie parsing falsy

Problem

I'm having problems while trying to parse back signed cookies in express/connect application.

io.set('authorization', function (handshakeData, callback) {
    if(handshakeData.headers.cookie) {
        var signedCookies = cookie.parse(decodeURIComponent(handshakeData.headers.cookie));
        handshakeData.cookie = connect.utils.parseSignedCookies(signedCookies, secret);
    } else {
        return accept('No cookie transmitted', false);
    }
    callback(null, true); // error first callback style 
});

What happens is call to connect.utils.parseSignedCookies returns empty object. I looked into source for parse function and found out that it calls unsign method which gets a substring of encoded value and then tries to sign it again with the same secret and compare the results to verify that its the same value encoded and for some reasons it fails and values does not match. I don't know what I'm doing wrong, why those values differs and why I'm unable to get correct session ID.

My app initialization code looks like this:

app.use(express.cookieParser(secret));
app.use(express.session({
    key: 'sessionID',
    secret: secret,
    maxAge: new Date(Date.now() + 3600000),
    store: new RedisStore({
        client: redisClient
    })
}));

Please help and point what I'm doing wrong here. Thank you

Problem courtesy of: Vytautas Butkus

Solution

The cookie parser is a middleware, so we have to use it like one. It will actually populate the object that you pass to it. This is how you would want to be using the parser:

// we need to use the same secret for Socket.IO and Express
var parseCookie = express.cookieParser(secret);

io.set('authorization', function(handshake, callback) {
  if (handshake.headers.cookie) {
    // pass a req, res, and next as if it were middleware
    parseCookie(handshake, null, function(err) {
      // use handshake.signedCookies, since the
      // cookie parser has populated it
    });
  } else {
    return accept('No session.', false);
  }
  callback(null, true);
});

The cookie parser API changed and this is what it looks like now:

module.exports = function cookieParser(secret) {
  return function cookieParser(req, res, next) {
    if (req.cookies) return next();
    var cookies = req.headers.cookie;

    req.secret = secret;
    req.cookies = {};
    req.signedCookies = {};

    if (cookies) {
      try {
        req.cookies = cookie.parse(cookies);
        if (secret) {
          req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
          req.signedCookies = utils.parseJSONCookies(req.signedCookies);
        }
        req.cookies = utils.parseJSONCookies(req.cookies);
      } catch (err) {
        err.status = 400;
        return next(err);
      }
    }
    next();
  };
};

So what we're doing is passing handshake as a request object, and the parser will read the headers.cookie property. Then, the cookies will be parsed, and put into req.signedCookies. Since we passed handshake as req, the cookies are now in handshake.signedCookies. Note that the cookies are only signed because you passed a secret to the parser.

Solution courtesy of: hexacyanide

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Connect signed cookie parsing falsy

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×