当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
但是当我查看数据库中的sessions集合时,我得到以下_id:
"_id" : "eFFkUnQXWdTO7GBRDc11No/a",
正如您所看到的,这对应于s:之后和期间之前的data.sessionID。我尝试使用两种不同的cookie解析器。下面的解析器的代码来自包含在express 3中的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);
}
});
答案 0 :(得分:3)
我遇到了同样的问题,当您的解决方案正常运行时,您使用的parseCookie函数来自较旧版本的connect。现在连接中的新代码签署了cookie,这是期间之后的额外字符。
在表达和连接的内容搞乱之后,我想出了以下代码。虽然它依赖于一些私有API函数connect(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);
}
});
答案 1 :(得分:1)
看来sessionStore键现在只是较短的uid(24)版本,而不再是存储在cookie中的“long”版本。
目前我通过做一个简单的拆分('。')[0]修复它来检索uid(24)部分: data.sessionID = cookie ['express.sid'] .split('。')[0];