phev8 phev8 - 3 months ago 18
Node.js Question

Allow connection only for authorised socket in sails.js

I am trying to implement some kind of security for socket.io clients in the sails.js backend (using version 0.12.x). To achieve this, I try to either prevent successful handshake for clients without a proper cookie (no authorised session beforehand) or like for HTTP request using passport.js to see if the client is authenticated.

In Sails.js documentation I've found that this should be possible, but I could not find any hint, how to do it really. On the other hand, looking for examples on the internet, people mostly don't use security for sockets, or use some old version of sails.js (<0.10).

The closest what I found until now, is for the

config/sockets.js
:

beforeConnect: function(handshake, cb) {
if (handshake.headers.cookie) {
console.log(handshake);
// TODO: check session authorization
} else {
return cb(null, false);
}
return cb(null, true);
},


This should check the cookie sent with the handshake, if it has a proper session. I have a hard time figuring out, how can I map the sid from the cookie to current sessions in sails.js, for deciding if the connection should be allowed.

Questions:


  • What is the best security practice for socket.io, if only a small number of clients is allowed (some 40-50 dynamic generated users should be allowed for connection), and nobody else?

  • How can I map the sails.sid from the cookie to active sessions?

  • What other configs could be a shortcut to my goal (e.g. setting some policies, that socket.io request use the same middleware as http)?



Thanks for any hint, link or suggestions.

Answer

What is the best security practice for socket.io, if only a small number of clients is allowed (some 40-50 dynamic generated users should be allowed for connection), and nobody else?

I don't know what is best. But there are two common approaches: token- and cookie based authentication.

Here is a nice visualization of both taken from https://auth0.com/blog/auth-with-socket-io/

enter image description here

I really like the token approach because there is no need for a session store. Hence the server application is decoupled from the client and also stateless.

How can I map the sails.sid from the cookie to active sessions?

Token approach: check out jsonwebtoken. When a user signs in you generate a token and send it to the client:

res.json({
    user: user,
    token: jwToken.issue({id : user.id })
});

Further you need a policy that checks if a token exists and validate it:

jwToken.verify(token, function (err, token) {
    if (err) return res.json(401, {err: 'Invalid Token!'});
    req.token = token; 
    next();
});

I found a complete tutorial that might help you: https://thesabbir.com/how-to-use-json-web-token-authentication-with-sails-js/

How to configure it with sails: you basically just send the token with each socket.io request and check the token inside a policy:

SailsJS - using sails.io.js with JWT

Comments