socket.io 和会话?

发布于 2024-10-11 17:53:12 字数 460 浏览 8 评论 0原文

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

寂寞笑我太脆弱 2024-10-18 17:53:12

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

为了使其工作,在express/connect方面,我显式定义了会话存储,以便我可以在套接字内使用它:

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

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

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

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.

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:

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.

染火枫林 2024-10-18 17:53:12

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

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

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

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

安稳善良 2024-10-18 17:53:12

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

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.io
I 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!

或十年 2024-10-18 17:53:12

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


我非常巧妙地完成了这项工作,而不必按照上面的 pr0zac 解决方案绕过 flashsocket 传输。我还在 Socket.IO 中使用express。方法如下。

首先,将会话 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 }));

希望这对在谷歌搜索时找到这篇文章的人有所帮助(就像我所做的那样;)

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:


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

First, pass the session ID to the view:

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:

<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:

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_store is Redis, using the redis-connect library.

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

吃颗糖壮壮胆 2024-10-18 17:53:12

请参阅: Socket.IO 身份验证

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

See this: Socket.IO Authentication

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

孤凫 2024-10-18 17:53:12

对于未来的读者 - 有一种优雅且简单的方法可以使用express-session 访问socket.io 内的会话。来自socket.io文档:

大多数现有的 Express 中间件模块应该与 Socket.IO 兼容,您只需要一点包装函数即可使方法签名匹配:

 const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);

结束请求-响应周期并且不调用 next() 的中间件函数将不起作用。

快速会话示例:

const session = require("express-session");
io.use(wrap(session({ secret: "cats" })));
io.on("connection", (socket) => {
   const session = socket.request.session; // here you get access to the session :)
});
 

For future readers - There is an elegant and easy way to access the session inside socket.io with express-session. From socket.io documentation:

Most existing Express middleware modules should be compatible with Socket.IO, you just need a little wrapper function to make the method signatures match:

 const wrap = middleware => (socket, next) => middleware(socket.request, {}, next);

The middleware functions that end the request-response cycle and do not call next() will not work though.

Example with express-session:

const session = require("express-session");
io.use(wrap(session({ secret: "cats" })));
io.on("connection", (socket) => {
   const session = socket.request.session; // here you get access to the session :)
});
 
陪你到最终 2024-10-18 17:53:12

查看 Socket.IO-connect

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

这将允许您将 Socket.IO 请求推送到 Express/Connect 中间件堆栈,然后使用 Socket.IO 事件处理程序进行处理,从而使您能够访问会话、cookie 等。不过,我不确定它是否适用于所有 Socket.IO 的传输。

Check out Socket.IO-connect

Connect WebSocket Middleware Wrapper Around Socket.IO-node
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.

她比我温柔 2024-10-18 17:53:12

我不确定我做得是否正确。
https://github.com/LearnBoost/socket.io/wiki/Authorizing

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

I am not sure that I am doing it right.
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)

瑕疵 2024-10-18 17:53:12

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

与 socket.io 共享基于 cookie 的快速会话中间件。与快递合作> 4.0.0和socket.io> 1.0.0 并且不会向后兼容。

为我工作!

You can make use of 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.

Worked for me!!

独留℉清风醉 2024-10-18 17:53:12

截至 2022 年 2 月,Socket.IO v4 支持此功能:

https: //socket.io/docs/v4/faq/#usage-with-express-session

const express = require('express');
const session = require('express-session');
const app = express();

const server = require('http').createServer(app);
const io = require('socket.io')(server);

const sessionMiddleware = session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }});
// register middleware in Express
app.use(sessionMiddleware);
// register middleware in Socket.IO
io.use((socket, next) => {
  sessionMiddleware(socket.request, {}, next);
  // sessionMiddleware(socket.request, socket.request.res, next); will not work with websocket-only
  // connections, as 'socket.request.res' will be undefined in that case
});

io.on('connection', (socket) => {
  const session = socket.request.session;
  session.connections++;
  session.save();
});

const port = process.env.PORT || 3000;
server.listen(port, () => console.log('server listening on port ' + port));

As of February 2022 this is supported by Socket.IO v4:

https://socket.io/docs/v4/faq/#usage-with-express-session

const express = require('express');
const session = require('express-session');
const app = express();

const server = require('http').createServer(app);
const io = require('socket.io')(server);

const sessionMiddleware = session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }});
// register middleware in Express
app.use(sessionMiddleware);
// register middleware in Socket.IO
io.use((socket, next) => {
  sessionMiddleware(socket.request, {}, next);
  // sessionMiddleware(socket.request, socket.request.res, next); will not work with websocket-only
  // connections, as 'socket.request.res' will be undefined in that case
});

io.on('connection', (socket) => {
  const session = socket.request.session;
  session.connections++;
  session.save();
});

const port = process.env.PORT || 3000;
server.listen(port, () => console.log('server listening on port ' + port));
蹲墙角沉默 2024-10-18 17:53:12

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

或者您可以使用:

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

希望这有帮助。

You can have a look at this: 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文