【问题标题】:How to access session in express, outside of the req?如何在请求之外以快递方式访问会话?
【发布时间】:2011-09-17 20:40:35
【问题描述】:

我知道我可以使用

function(req, res) {
    req.session
}

使用快递。但是我需要在响应函数之外访问会话。我该怎么做呢?

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

【问题讨论】:

  • 我最终做的只是在登录时给每个用户一个 uuid 并经常更改它,然后在套接字消息中使用它来验证他们是否真的是他们所说的那个人。

标签: javascript node.js express socket.io


【解决方案1】:

我想我有不同的答案。

代码:

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);
 });
}

我昨天测试了一下,效果很好。

【讨论】:

  • 天哪,这行得通! 3年后,这仍然是一个可靠的答案。踢。
【解决方案2】:

使用 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' );

【讨论】:

  • 这实际上几乎就是我们最终要做的!
【解决方案3】:

我相信检查socket.handshake 应该会让你获得会话:

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

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

【讨论】:

    【解决方案4】:

    假设你的 socket.io 代码看起来像这样:

    io.on('connection',
    function(client) {
      console.log(client.request)
    });
    

    请求是client.request,如上例所示。

    编辑: 作为一个单独的事情,也许这会有所帮助: https://github.com/aviddiviner/Socket.IO-sessions

    【讨论】:

    • 当我读到你的回复时我真的很兴奋,但是在打印了“client.request”变量的内容后,我发现出于某种原因,它们传递了除了会话之外的所有内容。不知道为什么不包括会话信息,它似乎应该在哪里。还有其他想法吗?
    • @user776796 您应该能够访问 cookie client.request.headers.cookie,并使用它来检查您的会话存储。
    • 很遗憾没有。 “headers.cookie”列出了我的 cookie,但其中不包含我的会话信息。
    猜你喜欢
    • 2015-10-23
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    相关资源
    最近更新 更多