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
。这样,(自定义命名空间的)套接字客户端在遇到错误时首先尝试连接到主命名空间,并且不会继续尝试连接到我们希望它连接到的自定义命名空间。但是, 在客户端上,我们在自定义命名空间上设置了错误处理程序,因此错误在主命名空间通道上传输,而不会被正在侦听自定义命名空间的客户端错误处理程序捕获,而自定义命名空间自主命名空间以来从未连接过连接失败。
总之,通过在主命名空间上设置中间件以防止未经授权的使用,尝试连接到自定义命名空间的客户端不会收到身份验证错误。
关于如何规避这种情况的任何想法?
谢谢