Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Session socket.io和会话?_Session_Node.js_Express - Fatal编程技术网

Session socket.io和会话?

Session socket.io和会话?,session,node.js,express,Session,Node.js,Express,我使用的是express framework。我想从socket.io访问会话数据。我尝试使用client.listener.server.dynamicViewHelpers数据来表示dynamicchelpers,但无法获取会话数据。有没有一个简单的方法可以做到这一点?请看代码 app.listen(3000); var io = require('socket.io'); var io = io.listen(app); io.on('connection', function(cli

我使用的是express framework。我想从socket.io访问会话数据。我尝试使用client.listener.server.dynamicViewHelpers数据来表示dynamicchelpers,但无法获取会话数据。有没有一个简单的方法可以做到这一点?请看代码

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

你可以看看这个:

或者,您也可以使用:

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

希望这能有所帮助。

这对通过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 }));
});
然后在我的套接字代码中,我包含了connect框架,这样我就可以使用它的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!!!!
    });
  }
});
然后,您可以根据需要使用会话。

请参见以下内容:


我建议不要通过
client.request…
client.listener…
获取任何内容,因为它不会直接连接到
客户端
对象,并且始终指向上次登录的用户

编辑:在尝试了一些不起作用的模块后,我实际上已经编写了自己的库来实现这一点。无耻插头:去看看吧。出于历史原因,我将在下面留下我的旧帖子:


根据上面的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'});"/>
在我的例子中,我的
session\u存储是Redis,使用
redisconnect

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

希望这能帮助那些在搜索Google时找到这篇文章的人(正如我所做的那样)

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


改为选中此选项(对于Socket.IO>=v0.7)。请参阅文档。

签出Socket.IO connect

围绕Socket.IO-node连接WebSocket中间件包装器


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

我不确定我是否做对了。


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

我建议不要完全重新发明轮子。您需要的工具已经是npm包了。我认为这就是您需要的: 我现在正在使用它,我想它会非常有用!!将express会话链接到socket.io层将有很多好处

你可以利用

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


为我工作

对于未来的读者,使用express session可以轻松优雅地访问socket.io中的会话。从socket.io文档:

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

但是,结束请求-响应周期且不调用next()的中间件函数将无法工作

快速会话示例:



我知道会话web套接字,但我不想为此使用库,我正在寻找一个简单的解决方案。我尝试了client.listener.server.viewHelpers;但是它返回了这样的结果:{}虽然这在一开始似乎是有效的,但它导致了比赛条件。我建议您完全避免使用它。最新版本的socket.io nodeBeware中似乎删除了socket\u client.request。。。现在有了新的惯例。。。我建议改为使用Socket.IO身份验证。请参阅@Jefferunfortuly的帖子,这将不再有效-parseCookie不再是connect utils的一部分。显然,它从来都不是公共api的一部分。还有一个混乱的替代方案——parseSignedCookie,但这也是私人的,所以我猜它也有消失的风险……现在我正在考虑这个。。。。为什么不将Cookie的存储区和套接字的存储区设置为同一个存储区?或者可以使用这个非常好的帖子:@FabianoPS-不再工作-connect不再提供它所依赖的parseCookie方法。@UptheCraek-既然connect不再使用parseCookie方法,这怎么可能呢?@Aust-好问题,我不知道现在最好的方法是什么。在我看来,这真是一团糟。令人烦恼的是,大多数解决方案讨论都集中在socket.io上(并不是每个人都在使用socket.io!)。现在有一个parseSignedCookie函数,但它也是私有的,因此它也有破坏更改的风险检查此SO问题:不幸的是,模块仍在使用插槽的v0.6。io@Jeffer-第二种解决方案在当前版本的connect中不再有效。-1
socket.io
是公开会话ID的内容,而不是该模块。这不是什么大问题,因为会话ID无论如何都存储在客户端的cookie中。。。此外,该教程不适用于最新版本的Express。您的解决方案链接只会重定向到
socket.io
github页面..?从安全角度来看,将会话id放入客户端html中不是一个好主意…当会话id已存储在本地html中时,为什么将会话id放入html中是一个坏主意cookie?因为cookie无法访问
var RedisStore = require('connect-redis');
var session_store = new RedisStore;
// ...
app.use(express.session({ store: session_store }));
 const wrap = middleware => (socket, next) => middleware(socket.request, {}, 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 :)
});