node.js socket.io 和会话?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4641053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:48:30  来源:igfitidea点击:

socket.io and session?

sessionnode.jsexpress

提问by sfs

I'm using express framework. I want to reach session data from socket.io. I tried express dynamicHelpers with client.listener.server.dynamicViewHelpers data, but i can't get session data. Is there a simple way to do this? Please see the code

我正在使用快速框架。我想从 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
    }); 
});

采纳答案by pr0zac

This won't work for sockets going over the flashsocket transport (it doesn't send the server the needed cookies) but it reliably works for everything else. I just disable the flashsocket transport in my code.

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

To make it work, in the express/connect side, I explicitly define the session store so I can use it inside socket:

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

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

Then inside my socket code, I include the connect framework so I can use its cookie parsing to retrieve the connect.sid from the cookies. I then look up the session in the session store that has that connect.sid like so:

然后在我的套接字代码中,我包含了连接框架,以便我可以使用它的 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!!!!
    });
  }
});

You can then use the session as needed.

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

回答by Jeffer

The Socket.IO-sessions module solution exposes the app to XSS attacks by exposing the session ID at the client (scripting) level.

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

Check this solutioninstead (for Socket.IO >= v0.7). See docs here.

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

回答by Francesco

I suggest not to entirely reinvent the wheel. The tools you need is already an npm package.I think this is what you need: session.socket.ioI am using it in these days and it will be very helpful I guess!! Linking the express-session to the socket.io layer will have so many advantages!

我建议不要完全重新发明轮子。你需要的工具已经是一个 npm 包了。我想这就是你需要的:session.socket.io我最近在用它,我猜它会很有帮助!!将 express-session 链接到 socket.io 层会有很多好处!

回答by Dave

Edit:After trying some modules that didn't work, I've actually gone and written my own library to do this. Shameless plug: go check it out at https://github.com/aviddiviner/Socket.IO-sessions. I'll leave my old post below for historical purposes:

编辑:在尝试了一些不起作用的模块后,我实际上已经编写了自己的库来做到这一点。无耻的插件:去https://github.com/aviddiviner/Socket.IO-sessions看看吧。出于历史目的,我将在下面留下我的旧帖子:



I got this work quite neatly without having to bypass the flashsockettransport as per pr0zac's solution above. I am also using express with Socket.IO. Here's how.

我非常巧妙地完成了这项工作,而无需按照pr0zac上面的解决方案绕过flashsocket传输。我也在 Socket.IO 中使用 express。就是这样。

First, pass the session ID to the view:

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

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

Then in your view, link it in with Socket.IO client-side:

然后在您的视图中,将其与 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'});"/>

Then in your server-side Socket.IO listener, pick it up and read/write the session data:

然后在您的服务器端 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
    });
  });
});

In my case, my session_storeis Redis, using the redis-connectlibrary.

就我而言,我session_store是 Redis,使用该redis-connect库。

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

Hope this helps someone who finds this post while searching Google (as I did ;)

希望这可以帮助那些在搜索谷歌时找到这篇文章的人(就像我一样;)

回答by Shripad Krishna

See this: Socket.IO Authentication

请参阅:Socket.IO 身份验证

I would suggest not fetching anything via client.request...or client.listener...as that is not directly attached to the clientobject and always point to the last logged in user!

我建议不要通过client.request...或获取任何东西,client.listener...因为它没有直接附加到client对象上,并且始终指向最后登录的用户!

回答by nonybrighto

You can make use of express-socket.io-session.

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

Share a cookie-based express-session middleware with socket.io. Works with express > 4.0.0 and socket.io > 1.0.0 and won't be backward compatible.

与 socket.io 共享一个基于 cookie 的 express-session 中间件。适用于 express > 4.0.0 和 socket.io > 1.0.0,并且不会向后兼容。

Worked for me!!

对我来说有效!!

回答by BMiner

Check out Socket.IO-connect

查看Socket.IO-connect

Connect WebSocket Middleware Wrapper Around Socket.IO-node https://github.com/bnoguchi/Socket.IO-connect

围绕 Socket.IO-node 连接 WebSocket 中间件包装器 https://github.com/bnoguchi/Socket.IO-connect

This will allow you to push the Socket.IO request(s) down the Express/Connect middleware stack before handling it with Socket.IO event handlers, giving you access to the session, cookies, and more. Although, I'm not sure that it works with all of Socket.IO's transports.

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

回答by Tan Nguyen

I am not sure that I am doing it right. https://github.com/LearnBoost/socket.io/wiki/Authorizing

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

With the handshake data, you can access to the cookies. And in the cookies, you can grab connect.sid which is the session id for each client. And then use the connect.sid to get the session data from database (I am assuming you are using RedisStore)

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

回答by intellidiot

You can have a look at this: https://github.com/bmeck/session-web-sockets

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

or alternatively you can use:

或者,您可以使用:

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

Hope this helps.

希望这可以帮助。