node.js - socket.io和session?

我使用快递框架。 我想从socket.io访问会话数据。 我尝试使用client.listener.server.dynamicViewHelpers数据表达dynamicHelpers,但我无法获取会话数据。 有一个简单的方法吗? 请参阅代码

app.listen(3000);

var io = require('socket.io');
var io = io.listen(app);

io.on('connection', function(client){
    // I want to use session data here
    client.on('message', function(message){
        // or here
    });
    client.on('disconnect', function(){
        // or here
    }); 
});
sfs asked 2019-08-13T17:21:07Z
9个解决方案
69 votes

这不仅适用于通过flashsocket传输的套接字(它不会向服务器发送所需的cookie),但它可以可靠地用于其他所有事情。 我只是在我的代码中禁用flashsocket传输。

为了使它工作,在快速/连接方面,我明确定义会话存储,以便我可以在套接字内使用它:

MemoryStore = require('connect/middleware/session/memory'),
var session_store = new MemoryStore();
app.configure(function () {
  app.use(express.session({ store: session_store }));
});

然后在我的套接字代码中,我包含了连接框架,因此我可以使用它的cookie解析来从cookie中检索connect.sid。 然后我在会话存储中查找具有connect.sid的会话,如下所示:

var connect = require('connect');
io.on('connection', function(socket_client) {
  var cookie_string = socket_client.request.headers.cookie;
  var parsed_cookies = connect.utils.parseCookie(cookie_string);
  var connect_sid = parsed_cookies['connect.sid'];
  if (connect_sid) {
    session_store.get(connect_sid, function (error, session) {
      //HOORAY NOW YOU'VE GOT THE SESSION OBJECT!!!!
    });
  }
});

然后,您可以根据需要使用会话。

pr0zac answered 2019-08-13T17:21:41Z
34 votes

Socket.IO-sessions模块解决方案通过在客户端(脚本)级别公开会话ID来使应用程序暴露于XSS攻击。

请改为检查此解决方案(对于Socket.IO> = v0.7)。 请参阅此处的文档。

Jeffer answered 2019-08-13T17:22:12Z
8 votes

我建议不要完全重新发明轮子。 你需要的工具已经是一个npm包。我认为这就是你需要的:session.socket.io我现在正在使用它,我猜它会非常有用! 将express-session链接到socket.io层将具有很多优势!

Francesco answered 2019-08-13T17:22:39Z
4 votes

编辑:在尝试了一些不起作用的模块之后,我实际上已经离开并编写了自己的库来执行此操作。 无耻的插件:请查看[https://github.com/aviddiviner/Socket.IO-sessions。]我将在下面留下我的旧帖子用于历史目的:


根据上面的pr0zac解决方案,我无需绕过flashsocket传输就可以完成这项工作。 我也使用Express与Socket.IO。 这是怎么回事。

首先,将会话ID传递给视图:

app.get('/', function(req,res){
  res.render('index.ejs', {
    locals: { 
      connect_sid: req.sessionID
      // ...
    }
  });
});

然后在您的视图中,将其与Socket.IO客户端链接:

<script>
  var sid = '<%= connect_sid %>';
  var socket = new io.Socket();
  socket.connect();
</script>
<input type="button" value="Ping" onclick="socket.send({sid:sid, msg:'ping'});"/>

然后在服务器端的Socket.IO监听器中,选择它并读取/写入会话数据:

var socket = io.listen(app);
socket.on('connection', function(client){
  client.on('message', function(message){
    session_store.get(message.sid, function(error, session){
      session.pings = session.pings + 1 || 1;
      client.send("You have made " + session.pings + " pings.");
      session_store.set(message.sid, session);  // Save the session
    });
  });
});

在我的情况下,我的session_store是Redis,使用redis-connect库。

var RedisStore = require('connect-redis');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));

希望这有助于在搜索Google时找到此帖子的人(就像我做的那样;)

Dave answered 2019-08-13T17:23:49Z
3 votes

请参阅:Socket.IO身份验证

我建议不要通过client.request...client.listener...获取任何内容,因为它不直接附加到client对象并始终指向最后一个登录用户!

Shripad Krishna answered 2019-08-13T17:24:21Z
2 votes

看看Socket.IO-connect

在Socket.IO节点周围连接WebSocket中间件包装器[https://github.com/bnoguchi/Socket.IO-connect]

这将允许您在使用Socket.IO事件处理程序处理它之前将Socket.IO请求推送到Express / Connect中间件堆栈,使您可以访问会话,cookie等。 虽然,我不确定它是否适用于所有Socket.IO的传输。

BMiner answered 2019-08-13T17:25:01Z
2 votes

您可以使用express-socket.io-session。

与socket.io共享基于cookie的快速会话中间件。 使用express&gt; 4.0.0和socket.io&gt; 1.0.0并且不会向后兼容。

为我工作!!

nonybrighto answered 2019-08-13T17:25:42Z
1 votes

你可以看看这个:[https://github.com/bmeck/session-web-sockets]

或者你可以使用:

io.on('connection', function(client) { 
  var session = client.listener.server.viewHelpers; 
  // use session here 
});

希望这可以帮助。

intellidiot answered 2019-08-13T17:26:17Z
1 votes

我不确定我做得对。[https://github.com/LearnBoost/socket.io/wiki/Authorizing]

使用握手数据,您可以访问cookie。 在cookie中,您可以获取connect.sid,它是每个客户端的会话ID。 然后使用connect.sid从数据库中获取会话数据(我假设您使用的是RedisStore)

Tan Nguyen answered 2019-08-13T17:26:50Z
translate from https://stackoverflow.com:/questions/4641053/socket-io-and-session