Socket.io 自定义命名空间客户端未收到来自主中间件的错误

mit*_*1os 5 authentication middleware namespaces node.js socket.io

我正在开发一个带有 socket.io 通信的项目。基本结构是我设置了一个需要身份验证的自定义命名空间。我通过 JWT (Json Web Tokens) 提供身份验证。

我的问题如下。身份验证作为命名空间中间件提供,如果失败,它会next使用Error. 如果我在自定义命名空间内实现身份验证,一切正常。前任。:

var io = require('socket.io')();
io
    .of('/somePath')
    .use(function authenticate(socket,next){
        if (authenticate.(socket)){
            var err = new Error('UnauthorizedError');
            next(err);
        }
        else{
            next();
        }
    })
    .on('connection',function(){
        console.log('Socket successfully connected to custom namespace /somePath');
    });

io.listen(3000);

//Client Code
var clientIO = require('socket.io-client');

var client = clientIO('http://localhost:3000/somePath');
client.on('connect',function(){
    console.log('Connected to host');
});
client.on('error',function(err){
    console.error(err);
});
Run Code Online (Sandbox Code Playgroud)

客户端通常从命名空间中间件接收错误。

但是,如果我想拥有更多共享相同身份验证逻辑的自定义命名空间,我必须分别为每个命名空间实现逻辑。前任。:

var io = require('socket.io')();
io
    .of('/somePath')
    .use(function authenticate(socket,next){
        if (authenticate.(socket)){
            var err = new Error('UnauthorizedError');
            next(err);
        }
        else{
            next();
        }
    })
    .on('connection',function(){
        console.log('Socket successfully connected to custom namespce /somePath');
    });

io
    .of('/someOtherPath')
    .use(function authenticate(socket,next){
        if (authenticate.(socket)){
            var err = new Error('UnauthorizedError');
            next(err);
        }
        else{
            next();
        }
    })
    .on('connection',function(){
        console.log('Socket successfully connected to custom namespce /someOtherPath');
    });

io.listen(3000);

//Client Code
var clientIO = require('socket.io-client');

var client = clientIO('http://localhost:3000/somePath');
client.on('connect',function(){
    console.log('Connected to host');
});
client.on('error',function(err){
    console.error(err);
});
Run Code Online (Sandbox Code Playgroud)

这又奏效了。这里的身份验证问题是,通过这种方式,我们仅为自定义命名空间设置了身份验证。默认命名空间/仍然不受保护,客户端无需任何凭据即可连接到它。

所以,我想,我应该使用身份验证机制作为主命名空间上的中间件,以便它必须通过它才能继续进行自定义命名空间连接。前任。:

//Server Code
var io = require('socket.io')();
io.use(function(socket,next){
    var err = new Error('I want an error');
    next(err);
})
io.on('connection', function(socket){
    console.log('Connected on main namespace');
});
io.listen(3000);
//Namespace
io
    //First Path
    .of('somePath')
    .on('connection',function(){
        console.log('Socket successfully connected to custom namespce /somePath');
    });
    //Second path
    .of('someOtherPath')
    .on('connection',function(){
        console.log('Socket successfully connected to custom namespce /someOtherPath');
    })

//Client Code
var clientIO = require('socket.io-client');

var client = clientIO('http://localhost:3000/somePath');
client.on('connect',function(){
    console.log('Connected to host');
});
client.on('error',function(err){
    console.error(err);
});
Run Code Online (Sandbox Code Playgroud)

请注意,中间件未设置在主命名空间上,也未设置在其他两个自定义命名空间上

这种方法无需身份验证即可解决与主命名空间的连接问题,但会产生其他问题!. 从 socket.io 连接到自定义命名空间的工作方式来看,它们首先连接到主命名空间/,然后连接到自定义提供的命名空间,(在这种情况下/somePath/someOtherPath。这样,(自定义命名空间的)套接字客户端在遇到错误时首先尝试连接到主命名空间,并且不会继续尝试连接到我们希望它连接到的自定义命名空间。但是, 在客户端上,我们在自定义命名空间上设置了错误处理程序,因此错误在主命名空间通道上传输,而不会被正在侦听自定义命名空间的客户端错误处理程序捕获,而自定义命名空间自主命名空间以来从未连接过连接失败。

总之,通过在主命名空间上设置中间件以防止未经授权的使用,尝试连接到自定义命名空间的客户端不会收到身份验证错误。

关于如何规避这种情况的任何想法?

谢谢