10

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?

James Parsons
6,09715 gold badges76 silver badges112 bronze badges
asked Jun 13, 2015 at 1:46
6
  • if the socket is still open. Then it always listening .Before that you should to confirm that all connection has been closed. If any of these do not close then live client will listen . thanks. Commented Jun 13, 2015 at 2:36
  • You don't want to temporarily disconnect the socket. socket.io has an authentication scheme that you can plug in to so that the socket is never accepted if it doesn't authenticate. Keep in mind that all webSocket connections start with an http request so if you're already authenticated via http, you can use that for the webSocket too. Also deleting a socket from io.sockets.connected does not disconnect the socket. Commented Jun 13, 2015 at 2:38
  • I use the rest api to authenticate a user so they can use the service. As far as I know, I can authenticate the user but I can't authenticate the socket.io session the same way. My idea was to use tokens to assure that the person using the socket is the one that is authenticated Commented Jun 13, 2015 at 2:42
  • See this article for an example. If you set a cookie when the rest api is authenticated, then you can access that cookie in the socket.io middleware to determine authenticated or not. Or, you can launch a separate auth process from the socket.io middleware. The ability to access http cookies or do your own auth is built into socket.io so you don't have to disconnect while you do auth, you can just auth as part of the connection process. Commented Jun 13, 2015 at 2:47
  • let me create a example how you can auth your socket clients with the same token used with http server. Commented Jun 13, 2015 at 2:49

2 Answers 2

12

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

answered Jun 13, 2015 at 2:28
Sign up to request clarification or add additional context in comments.

4 Comments

How could I reconnect after auth is complete? Would it be as simple as socket.reconnect()?
There's no need to disconnect before auth. socket.io has authentication middleware. One can just plug directly into that and the socket won't get connected in the first place until it authenticates.
@WilsonBalderrama I did attempt this but I couldn't get it to work via this framework for iOS. github.com/socketio/socket.io-client-swift. The problem was that I would get an error of no headers sent each time.
@AlexCatchpole I don't have any experience with iOS but are you using this method for connecting? I think it would be "connectParams": [ "token": userToken ]
0

socket.io also saves the sockets in a namespace (the default if not specified) and there's where you need to delete it for it to stop receiving messages.

See this post for a step by step explanation of what you're trying to do, and this module that abstracts the whole process.

answered Jul 19, 2015 at 18:42

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.