通过使用给定的示例,我有一个相应的问题。
在该示例中,通过首先重新加载 session 来在WebSocket中使用该 session :
socket.on('set value', function (val) {
sess.reload(function () {
sess.value = val;
sess.touch().save();
});
});
尝试在我自己的应用程序中使用它时,出现以下异常:
sess.reload(function () {
^
TypeError: Object #<Object> has no method 'reload'
我认为问题是,没有人将变量sess定义为 session :
io.listen(app).set('authorization', function (data, accept) {
if (!data.headers.cookie)
return accept('No cookie transmitted.', false);
data.cookie = parseCookie(data.headers.cookie);
data.sessionID = data.cookie['express.sid'];
store.load(data.sessionID, function (err, session) {
if (err || !session) return accept('Error', false);
data.session = session;
return accept(null, true);
});
})
也许有人对此有一个简短的解决方法?
解决的问题:我尝试使用以下示例:带有Express 3.0和Redis的https://github.com/DanielBaulig/sioe-demo/blob/master/app.js。
因此,我创建了Redis存储(connect-redis)而不是MemoryStore:
app.use(express.session({cookie: {expires: new Date(Date.now() + 30*60*60*24*1000)}, secret: SESSION_SECRET, key: SESSION_KEY, store: new RedisStore({host:'localhost', port:'6379', client: dbRedis})}));
由于连接中的parseCookie-Method移动了,所以我使用了
parseCookie = require('cookie').parse
代替
connect.utils.parseCookie
为了访问cookie中的 session ,我通过使用以下示例修改了示例:
sio.set('authorization', function (data, accept) {
if (!data.headers.cookie)
return accept('No cookie transmitted.', false);
data.cookie = parseCookie(data.headers.cookie);
log.info('Cookie: $s', JSON.stringify(data.cookie));
data.sessionID = data.cookie['letter.sid'];
log.info('SessionId: %s', data.sessionID);
dbRedis.get(data.sessionID, function (err, session) {
if (err || !session) return accept('Error ' + session, false);
data.session = session;
return accept(null, true);
});
})
现在我的问题是,我无法从Redis加载 session ,因为 session ID不同
我在页面上打印 session ID(req.sessionID),我得到:n + 57bnkLr + iXkMLbStWdFzK5
但是在Redis中存储了以下ID:
[2012-12-03T22:14:56.632Z] INFO: Postbox/78964 on capns-mba.local: Cookie: $s {"SQLiteManager_currentLangue":"4","connect.sid":"s:xvYdDm5C0MEIg53EG8JgqBnM.Tx8+PMKa570zk6qt9vmCjRz2p/LP/COyyqGSm+VKxww","letter.sid":"s:n+57bnkLr+iXkMLbStWdFzK5.XPHh1xXrK9D4cPfJ7HcHO11PKk8FXLg6fIRGaWb/+jI"}
[2012-12-03T22:14:56.632Z] INFO: Postbox/78964 on capns-mba.local: SessionId: s:n+57bnkLr+iXkMLbStWdFzK5.XPHh1xXrK9D4cPfJ7HcHO11PKk8FXLg6fIRGaWb/+jI
显然req.sessionID是保存在cookie/redis中的SessionID的一部分-但是为什么呢?哪个是正确的sessionID?
最佳答案
查看session middleware的这段代码(第267行):
var val = 's:' + signature.sign(req.sessionID, secret);
其中
signature.sign
函数是一个串联(伪代码):req.sessionID + "." + hash(secret)
其中
hash
是自定义函数(see this for more details)。这意味着它只是cookie的签名约定(以使其更加安全)。您可以通过以下方式检索sid:
var signature = require( "cookie-signature" ),
prefix = "s:";
var real_sid = sid.replace( prefix, "" );
real_sid = signature.unsign( real_sid, SESSION_SECRET );