首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Socket.IO身份验证与共享会话数据,io.use()是如何工作的?

Socket.IO身份验证与共享会话数据,io.use()是如何工作的?
EN

Stack Overflow用户
提问于 2018-04-26 07:15:05
回答 2查看 0关注 0票数 0

受到如何与Socket.IO 1.x和Express 4.x共享会话的启发,我以某种“干净”的方式实现了套接字认证,无需使用cookie解析器并从头文件中读取cookie,但很少有项目对我来说仍不清楚。示例使用上一个稳定的socket.io版本1.3.6。

代码语言:javascript
运行
复制
var express      = require('express'),
    session      = require('express-session'),
    RedisStore   = require('connect-redis')(session),
    sessionStore = new RedisStore(),
    io           = require('socket.io').listen(server);

var sessionMiddleware = session({
    store   : sessionStore,
    secret  : "blabla",
    cookie  : { ... }
});

function socketAuthentication(socket, next) {
  var sessionID = socket.request.sessionID;

  sessionStore.get(sessionID, function(err, session) {
      if(err) { return next(err); }

      if(typeof session === "undefined") {
          return next( new Error('Session cannot be found') );
      }
      console.log('Socket authenticated successfully');
      next();
  });
}

io.of('/abc').use(socketAuthentication).on('connection', function(socket) { 
  // setup events and stuff
});

io.use(function(socket, next) {
  sessionMiddleware(socket.request, socket.request.res, next);
});

app.use(sessionMiddleware);
app.get('/', function(req, res) { res.render('index'); });
server.listen(8080);

index.html

代码语言:javascript
运行
复制
<body>
    ...
    <script src="socket.io/socket.io.js"></script>
    <script>
       var socket = io('http://localhost:8080/abc');
    </script>
</body>

所以io('http://localhost:8080/abc');从客户端发送初始HTTP握手请求到服务器,从服务器可以收集cookie和许多其他请求信息。所以服务器可以通过socket.request访问该初始请求。

我的第一个问题是为什么握手请求不在快速会话中间件的范围之内?(更普遍地在app.use中间件范围内?)在某种程度上,我预计这个app.use(sessionMiddleware); 在该初始请求之前触发,然后轻松访问socket.request.session

其次,中间件定义的场景io.use()会发生什么?仅用于初始HTTP握手请求?它似乎io.use()是用于套接字相关的东西(问题是:什么东西),而app.use标准的请求。

我不太清楚为什么在上面的例子中io.use()被解雇了io.of('/abc').use()。我故意写下这个命令,io.of('/abc').use()首先看它是否会起作用,并且工作正常。应该反过来写。

最后,socket.request.res也像一些人在链接问题中指出的,有时undefined导致应用程序崩溃,问题可以通过提供空对象而不是socket.request.res来解决

EN

Stack Overflow用户

发布于 2018-04-26 16:52:00

为什么握手请求不在快速会话中间件的范围内?

因为socket.io将附加到一个http.Server,它是快速下的图层。它在socket.io 的源代码中的评论中提到。

这是因为第一个请求是一个常规的http请求,用于将请求的无状态http连接升级为完全状态的websocket连接。因此,它必须通过适用于常规http请求的所有逻辑,这没什么意义。

使用io.use()定义的中间件会触发哪些场景?

每当创建一个新的套接字连接时。

所以每次客户端连接时都会调用使用io.use()注册的中间件。然而,一旦客户端连接上了,当从客户端接收到数据包时它就不会被调用。如果连接是在自定义命名空间或主命名空间上启动的,则无关紧要,它将始终被调用。

为什么io.use()在io.of('/ abc')。use()之前触发?

命名空间是socket.io实现的一个细节,事实上,websockets将始终首先命中主命名空间。

为了说明这种情况,请看这段代码和它产生的输出:

代码语言:javascript
运行
复制
var customeNamespace = io.of('/abc');

customeNamespace.use(function(socket, next){
  console.log('Use -> /abc');

  return next();
});

io.of('/abc').on('connection', function (socket) {
  console.log('Connected to namespace!')
});

io.use(function(socket, next){
  console.log('Use -> /');

  return next();
});

io.on('connection', function (socket) {
  console.log('Connected to namespace!')
});

输出:

代码语言:javascript
运行
复制
Use -> /
Main namespace
Use -> /abc
Connected to namespace!

查看socket.io团队添加到他们的文档中的警告:

重要说明:命名空间是Socket.IO协议的实现细节,并且与底层传输的实际URL无关,默认为/socket.io/...。

为什么socket.request.res未定义?

据我所知,它永远不应该是未定义的。这可能与您的具体实施有关。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档