Socket.io自定义命名空间客户端不会从主中间件

时间:2015-10-29 11:02:02

标签: node.js authentication namespaces socket.io middleware

我正在使用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);
});

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

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

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

这又一次有效。这里的身份验证问题是这样,我们只为自定义命名空间设置了身份验证。默认命名空间/仍然不受保护,客户端可以在没有任何凭据的情况下连接到它。

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

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

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

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

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

关于如何规避这一点的任何想法?

由于

0 个答案:

没有答案