【问题标题】:Connect signed cookie parsing falsy连接签名的 cookie 解析错误
【发布时间】:2013-09-23 19:11:55
【问题描述】:

我在尝试在 express/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 会返回空对象。我查看了 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
    })
}));

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

【问题讨论】:

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


    【解决方案1】:

    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 传递给了解析器。

    【讨论】:

    • 感谢您的回答,这样做更有意义,但不幸的是,由于某些原因它也不起作用。这是签名和重新签名值的屏幕截图 - 它仍然不同:grab.by/qyra 我真的不知道该怎么做......
    • 解析部分的代码与您的代码几乎相同。但是我不确定我是否正确地将它添加为中间件。它在会话中间件和路由器中间件之前。回家后我会尝试发布整个代码,也许会有任何想法..
    • 该死的,似乎一切都很好。问题是我在连接到 socketio 服务器时使用了 IP 地址,而我在localhost 上打开了浏览器。这导致在发送套接字握手请求时将错误的 cookie 发送到服务器......愚蠢的我......
    【解决方案2】:

    我在 cookie/sessions/socket.io 等方面遇到了左右问题。最后是 @vytautas 评论帮助了我。如果有人看到这一点,请确保您连接到正确的主机,无论您是否将其设置为 localhost 或 IP 地址或您有什么。否则,您将无法解析传入的 cookie。

    (事后看来有点明显。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 2014-02-18
      • 2019-10-01
      相关资源
      最近更新 更多