2015-06-13 88 views
6

我将尝试验证socket.io上的连接。Socket.io中的身份验证

当前,首先通过REST API对用户进行身份验证,然后,我向用户发送JsonWebToken以及经过身份验证的用户的用户名。打开客户端和服务器之间的连接后,我的计划是暂时从连接的套接字列表中删除该套接字,以防止在执行身份验证时在服务器之间接收和发送数据。

在这个验证中,我验证令牌,如果令牌有效,我重新将套接字的ID添加到连接的套接字列表中。唯一的问题是第一部分不起作用。我似乎无法从列表中删除套接字。

为了测试这个,我做了以下工作。

io.on('connection', function(socket){ 
    //temp delete socket 
    delete io.sockets.connected[socket.id]; 
    console.log(io.sockets.connected); 
    socket.emit("test"); 
}); 

正如你可以看到我删除插座,并发出测试事件,看看如果套接字仍然是开放的。该消息在客户不应该收到时收到。

有谁知道为什么会发生这种情况?

+0

如果套接字仍然打开。然后它总是在倾听。在此之前,您应该确认所有连接已关闭。如果其中任何一个都没有关闭,那么客户端会听。 谢谢。 –

+0

你不想暂时断开插座。 socket.io具有可以插入的身份验证方案,以便在未验证身份验证的情况下永远不会接受套接字。请记住,所有webSocket连接都以http请求开始,因此如果您已通过http进行身份验证,则也可以将其用于webSocket。同样从'io.sockets.connected'删除套接字不会断开套接字。 – jfriend00

+0

我使用其余api来验证用户,以便他们可以使用该服务。据我所知,我可以验证用户,但我无法以同样的方式验证socket.io会话。我的想法是使用标记来确保使用套接字的人是经过身份验证的人 –

回答

9

尝试使用断开方法从Socket对象,像这样:

io.on('connection', function(socket){ 
    //temp delete socket 
    socket.disconnect(); 

    console.log(io.sockets.connected); 
    socket.emit("test"); 
}); 

UPDATE:

例如,如果你的HTTP服务器会为客户端的令牌:

app.post('/api/users', function (req, res) { 
    var user = { 
    username: req.body.username 
    }; 

    var token = jwt.sign(user, secret, {expiresInMinutes: 30}); 

    res.json({token: token}); 
}); 

然后你可以重用该令牌到验证你的websocket连接。

从客户端(HTML文件)发送代码令牌将是:

socket = io.connect('http://localhost:4000', { 
    query: 'token=' + validToken, 
    forceNew: true 
}); 

,并在服务器(socketio)的socketio授权码将是:

// here is being used a socketio middleware to validate 
// the token that has been sent 
// and if the token is valid, then the io.on(connection, ..) statement below is executed 
// thus the socket is connected to the websocket server. 
io.use(require('socketio-jwt').authorize({ 
    secret: secret, 
    handshake: true 
})); 



// but if the token is not valid, an error is triggered to the client 
// the socket won't be connected to the websocket server. 
io.on('connection', function (socket) { 
    console.log('socket connected'); 
}); 

注意的秘密在express上使用它来生成一个标记,同样的标记也被用在socketio中间件的验证标记上。

我已经创建了一个例子,你可以看到这种验证是如何工作的,源代码是在这里:https://gist.github.com/wilsonbalderrama/a2fa66b4d2b6eca05a5d

复制它们的文件夹中,然后运行与节点server.js然后访问HTML文件从这个URL浏览器:http://localhost:4000

但首先安装模块:socket.io,快递,socketio,智威汤逊,jsonwebtoken

+0

身份验证完成后,我如何重新连接?它会像socket.reconnect()一样简单吗? –

+0

认证前无需断开连接。 socket.io具有认证中间件。你可以直接插入它,并且套接字不会首先被连接,直到它被认证。 – jfriend00

+0

@WilsonB​​alderrama我确实尝试过,但是我无法通过iOS的这个框架获得它的工作。 https://github.com/socketio/socket.io-client-swift。问题是我会得到每次没有发送头的错误。 –

0

socket.io也节省了插座的命名空间(默认如果未指定)并且你需要删除它以停止接收消息。

请参阅this post一步一步解释你想要做什么,this module摘要整个过程。