socket.io cookie解析握手错误

socket.io cookie parse handshake error

本文关键字:错误 io cookie socket      更新时间:2023-09-26

当socket.io查找会话时,我会收到一个握手错误,因为cookie的id与数据库中的id不匹配。我使用的是Express3、mongodb、connect mongodb和socket.io v0.9.10

例如,包含socket.io代码的console.log(data.sessionID)的结果将打印出来:

s:eFFkUnQXWdTO7GBRDc11No/a.U6voj5QnxKs1skq766nO7/qJvPEJA73KaQM67qNEs/k

但是,当我查看数据库上的会话集合时,我得到了以下id:

"_id" : "eFFkUnQXWdTO7GBRDc11No/a",

正如您所看到的,这对应于s之后和句点之前的data.sessionID。我尝试使用两个不同的cookie解析器。下面的解析器代码来自express3中包含的cookie模块。我不确定是否每个cookie ID都遵循这种模式,所以我不知道我是否应该自己再次解析结果,或者我是否做错了什么。

exports.parseCookie = function(str) {
var obj = {}
var pairs = str.split(/[;,] */);
var encode = encodeURIComponent;
var decode = decodeURIComponent;
pairs.forEach(function(pair) {
    var eq_idx = pair.indexOf('=')
    var key = pair.substr(0, eq_idx).trim()
    var val = pair.substr(++eq_idx, pair.length).trim();
    // quoted values
    if ('"' == val[0]) {
        val = val.slice(1, -1);
    }
    // only assign once
    if (undefined == obj[key]) {
        obj[key] = decode(val);
    }
});
return obj;

};

下面的代码给了我一个握手错误,因为"connect.sid"属性与数据库中的id属性不匹配。

io.set('authorization', function (data, accept) {
    if (data.headers.cookie) {
        data.cookie = utils.parseCookie(data.headers.cookie);
        data.sessionID = data.cookie['connect.sid'];
        // **************** //
        console.log(data.sessionID);
        // **************** //
        sessionStore.get(data.sessionID, function (err, session) {
            if (err || ! session) {
                accept('Error', false);
            } else {
                data.session = session;
                data.session.url = data.headers.referer;
                accept(null, true);
            }
        });
    } else {
       return accept('No cookie transmitted.', false);
    }
});

我遇到了同样的问题,虽然您的解决方案有效,但您使用的parseCookie函数来自旧版本的connect。connect中的新代码现在对cookie进行签名,cookie是句点之后的额外字符。

在对express和connect的核心进行了一些混乱之后,我想出了以下代码。虽然它依赖于connect的某些专用API函数(utils.parseSignedCookies),但它至少使用与生成cookie相同的代码来解析cookie,因此对cookie的创建和解析方式的未来变化不太敏感。

/* cookie: the cookie string from the request headers
 * sid: the session 'key' used with express.session()
 * secret: the session 'secret' used with express.session()
 */
function parseSessionCookie(cookie, sid, secret) {
  var cookies = require('express/node_modules/cookie').parse(cookie)
    , parsed = require('express/node_modules/connect/lib/utils').parseSignedCookies(cookies, secret)
    ;
  return parsed[sid] || null;
}
socketIO.set('authorization', function(data, accept) {
  var sid = parseSessionCookie(data.headers.cookie, 'express.sid', 'secret');
  if (sid) {
    sessionStore.get(sid, function(err, session) {
      if (err || !session) {
        accept('Error', false);
      } else {
        data.session = session;
        accept(null, true);
      }
    });
  } else {
    return accept('No cookie transmitted.', false);
  }
}); 

sessionStore密钥现在似乎是较短的uid(24)版本,而不再是存储在cookie中的"long"版本。

目前,我通过执行简单的split('.')[0]来检索uid(24)部分来修复它:data.sessionID=cookie['express.sid'].split('.')[0];