连接已签名的cookie解析falsy

时间:2013-09-23 19:11:55

标签: javascript node.js express socket.io connect

我在尝试解析快递/连接应用程序中签名的cookie时遇到了问题。

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 
});

调用connect.utils.parseSignedCookies会返回空对象。我查看了source for parse函数,发现它调用unsign方法获取编码值的子字符串,然后尝试用相同的秘密再次签名,并比较结果以验证其编码的相同值,并且由于某些原因它失败,值不匹配。我不知道我做错了什么,为什么这些值不同以及为什么我无法获得正确的会话ID。

我的应用初始化代码如下所示:

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

请帮助并指出我在这里做错了什么。谢谢

2 个答案:

答案 0 :(得分:2)

cookie解析器是一个中间件,所以我们必须像它一样使用它。它实际上会填充您传递给它的对象。这就是你想要使用解析器的方式:

// 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);
});

Cookie解析器API已更改,现在看起来像这样:

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();
  };
};

所以我们正在做的是将handshake作为请求对象传递,解析器将读取headers.cookie属性。然后,将解析cookie,并将其放入req.signedCookies。由于我们将handshake作为req传递,因此Cookie现在位于handshake.signedCookies。请注意,cookie只是因为您将secret传递给解析器而签名。

答案 1 :(得分:0)

我在使用cookies / sessions / socket.io等时左右问题。终于@vytautas的评论帮助了我。如果有人看到这个,请确保您连接到正确的主机,无论您将其设置为localhost还是IP地址,或者您有什么。否则,您将无法解析传入的cookie。

(事后看来有点明显。)