Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authentication in Socket.io

I'm going to try to authenticate a connection on socket.io.

Currently, the user is first authenticated via a REST API, then, I send the user a JsonWebToken with the authenticated user's username. After I open the connection between the client and the server, my plan is to temporarily delete that socket from the list of connected sockets to prevent the receiving and sending of data between the server while I carry out the auth.

In this auth, I verify the token and if the token is valid I re-add the socket's id to the list of connected sockets. The only problem is that the first part doesn't work. I can't seem to delete the socket from the list.

To test this I did the following.

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

As you can see I delete the socket and emit a test event to see if the socket is still open. The message was received by the client when it shouldn't be.

Does anyone know why this occurs?

like image 318
Alex Catchpole Avatar asked Jun 13 '15 01:06

Alex Catchpole


1 Answers

Try using disconnect method from the socket object, something like this:

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

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

UPDATE:

For example if your HTTP server gives to a client a token:

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

then you can reuse that token to authenticate your websocket connections.

The token sending code from the client (html file) will be:

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

and the socketio authorization code in the server(socketio) will be:

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

Note that the secret used on the express to generate a token, the same token is being used too on the validation token at socketio middleware.

I have created an example where you can see how this kind of validation works, the source code is here: https://gist.github.com/wilsonbalderrama/a2fa66b4d2b6eca05a5d

copy them in a folder and run the server.js with node and then access the html file from the browser at this URL: http://localhost:4000

but first install the modules: socket.io, express, socketio-jwt, jsonwebtoken

like image 114
Wilson Avatar answered Oct 13 '22 00:10

Wilson