如何在express中访问会话(session),而不是通过req对象访问?

23
我明白了,以下是您需要翻译的内容:

我知道可以使用

function(req, res) {
    req.session
}

使用express。但是我需要在响应函数之外访问会话(session)。我该如何处理?

我正在使用socket.io来传递添加帖子和评论的信息。因此,当我在服务器端接收到socket.io消息时,我需要使用会话来验证发布信息的人。但是由于这是通过socket.io完成的,所以没有req/res。


我最终做的是在每次用户登录时为其分配一个uuid,并经常更改它,然后在套接字消息中使用该uuid来验证他们确实是自己所说的那个人。 - MrBojangles
4个回答

12

我认为我的答案不同。

code:

var MongoStore = require('connect-mongo')(session);
var mongoStore = new MongoStore({
    db:settings.db,            //these options values may different
    port:settings.port,
    host:settings.host
})
app.use(session({
    store : mongoStore
    //here may be more options,but store must be mongoStore above defined
}));

那么您应该在req中定义一个会话键,就像这样:

代码:

req.session.userEmail;

最终,您可以通过以下方式获得:

代码:

var cookie = require("cookie"); //it may be defined at the top of the file
io.on("connection",function(connection){

 var tS = cookie.parse(connection.handshake.headers.cookie)['connect.sid'];
 var sessionID = tS.split(".")[0].split(":")[1];
 mongoStore.get(sessionID,function(err,session){
      console.log(session.userEmail);
 });
}

昨天我测试了它,它运行良好。


天啊,这个可行!三年过去了,这仍然是一个很好的答案。太棒了。 - NetOperator Wibby

7
使用socket.io,我已经以一种简单的方式完成了这个任务。我假设你有一个用于你的应用程序的对象,比如说MrBojangle,而对于我的应用程序,它被称为Shished:
/**
 * Shished singleton. 
 *
 * @api public
 */
function Shished() {
};


Shished.prototype.getHandshakeValue = function( socket, key, handshake ) {                          
    if( !handshake ) {
        handshake = socket.manager.handshaken[ socket.id ];                                         
    }
    return handshake.shished[ key ];                                                                
};                                                                                                  

Shished.prototype.setHandshakeValue = function( socket, key, value, handshake ) {                   
    if( !handshake ) {
        handshake = socket.manager.handshaken[ socket.id ];                                         
    }
    if( !handshake.shished ) {
        handshake.shished = {};                                                                     
    }
    handshake.shished[ key ] = value;                                                               
};

关于授权方法,我正在使用MongoDB进行会话存储:

io.set('authorization', function(handshake, callback) {
    self.setHandshakeValue( null, 'userId', null, handshake );
    if (handshake.headers.cookie) {
        var cookie = connect.utils.parseCookie(handshake.headers.cookie);
        self.mongoStore()
        .getStore()
        .get(cookie['connect.sid'], function(err, session) {
            if(!err && session && session.auth && session.auth.loggedIn ) {
                self.setHandshakeValue( null,
                            'userId',
                            session.auth.userId,
                            handshake );
            }
        });
    }

在将记录保存到模型之前,您可以执行以下操作:

model._author = shished.getHandshakeValue( socket, 'userId' );


注:本文涉及IT技术相关内容。

这实际上几乎就是我们最终所做的! - MrBojangles

1

我相信检查 socket.handshake 应该可以获取到session:

io.sockets.on('connection', function(socket) { 
  console.log(socket.handshake.sessionID);
});

当客户端与您的socket.io服务器建立套接字连接时,客户端会发送WebSocket握手请求。我上面所做的是从握手中获取会话ID。

0
假设你的socket.io代码看起来像这样:
io.on('connection',
function(client) {
  console.log(client.request)
});

请求是如上示例所示的 client.request

编辑: 另外一件事,也许这会有帮助: https://github.com/aviddiviner/Socket.IO-sessions


当我看到你的回复时,我感到非常兴奋,但在打印“client.request”变量的内容后,我发现除了会话之外,他们几乎传递了所有其他内容。不确定为什么会话信息没有被包含,它似乎应该在那里。还有其他想法吗? - MrBojangles
1
@user776796,您应该能够访问cookie client.request.headers.cookie,并使用它来检查您的会话存储。 - Harry
很遗憾,"headers.cookie" 中列出了我的 cookie,但我的会话信息并未包含在其中。 - MrBojangles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接