【问题标题】:Session Property not saving in session store when retrieving from socket.io从 socket.io 检索时,会话属性未保存在会话存储中
【发布时间】:2014-09-10 22:14:30
【问题描述】:

我想要完成的是将当前用户的用户名存储在会话中,以便可以通过 socket.io 检索。

目前,我让客户端将其 sessionId 发送到 socket.io 端点(通过 io.connect):

var socket = io.connect('http://localhost?sessionId=' + sessionid);

然后在服务器端,我有:

io.use(function(socket, callback) {

    if (socket && socket.handshake && socket.handshake.query && socket.handshake.query.sessionId) {
        var sessionId = socket.handshake.query.sessionId;
        sessionStore.get(sessionId, function(error, session) {
            socket.handshake.sessionId = sessionId;

            if (error) {
                callback('Could not set session id with socket io authorization handshake!', false);
            } else if (!session) {
                callback('There was no session found during socket io authorization handshake!', false);
            } 

            console.log(session);

            socket.session = session;
            callback(null, true);
        });
    } else {
        callback('No sessionId value was provided in query string to socket io connect from client', false);
    }
});

这会从客户端提供的 sessionid 正确检索会话(当然,假设 id 存在)。

现在,我想要做的是能够通过会话从 socketio 处理程序中获取由 passportjs 管理的用户名。

所以,首先,我在路由器控制器中有此端点的代码:

router.get('/',  Authentication.redirectIfNotAuthenticated, function(req, res) {
    req.session.user = req.user;
    console.log(req.session);

    res.locals.sessionId = req.session.id;
    res.render('mypage', { title: 'This is my page', user: req.user });
});

console.log(req.session) 确实向我表明 req.user 已正确插入到会话对象中并且是可见的。 Authentication.redirectIfNotAuthenticated 使用的是 passportjs,并且非常简单(包含代码以防出现问题):

redirectIfNotAuthenticated : function(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }

    res.redirect('/');
}

所以...我们知道用户正在作为属性插入到会话对象中...但是当我点击我的 socketio 方法之一时:

socket.on('init', function(info) {
    console.log(socket.session);
    ...
});

那个 console.log(socket.session) 不会显示我在路由中修改的会话,而是显示“原始”会话对象 - 就好像我根本没有添加任何东西一样!我知道socket.on('init'... 是在我上面详述的io.use(function.... 代码之后调用的(会话从sessionStore 中提取并保存在套接字对象中)。

我只是无法追查为什么存储在 socket.session 中的会话(从会话存储中检索)没有反映路由器中对会话所做的最新更改。

如果有人有任何建议,或者我期望看到的内容不正确的原因,我会很高兴听到他们的意见!

【问题讨论】:

    标签: express socket.io passport.js


    【解决方案1】:

    会话限定专用客户端浏览器选项卡和服务器之间的连接。

    由于您没有解释为什么要将用户名存储在会话中,我只能根据猜测来回答:

    1. 如果您想记住用户名以供以后在会话中使用,请将其存储在客户端。
    2. 如果您想向通信空间中的其他用户声明用户名(和其他变量),最简单的方法是将数据存储在数据库中(请注意,数据库可以在内存中,这可以解决要快)。您也可以适应文件 - 但如果您运行多个用户,则无论如何您都必须切换到数据库...

    无论如何,都没有必要将会话的范围扩展到多个客户端。

    【讨论】:

    • 我相信你用 2 确定了我的用例。我确实希望向其他用户声明用户名,但我想这应该通过其他一些信息而不是会话来完成(通过会话 ID) , 正确的?正如您所说,会话限定了客户端实例和服务器之间的连接(而我将其视为用户的标识符......这本身并不正确,但可能不是理想的方法)。
    • 正确。如果用户的真实性很重要,您需要通过身份验证来涵盖这一点 - 密码和用户名用于数据库。如果用户通过身份验证,该信息可以存储在服务器上的会话中。但是,这种身份验证状态是您首先不会跨会话边界线进行通信的。出于信息目的,您可以另外将其存储在数据库中以让其他人知道。
    猜你喜欢
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 2012-09-06
    • 2012-12-23
    • 2012-12-10
    • 1970-01-01
    • 2010-12-06
    相关资源
    最近更新 更多