1

I'm building a realtime mobile app (native) and I'm interested in starting the app from a user login screen and then move on.

I figured I need Express + primus with socket.io (or sockjs) + passport.socketio + redis (not 100% sure I need redis yet) to build my backend.

Node.js placeholder

I even found this step by step tutorial which is really helpful, it takes me step by step to making a secure api.

My question is a double one:

  1. How can I tweak this example to use TOKENS instead of cookies (since I'm building a native mobile app and not a browser web app) and its more secure according to this.
  2. How to bind express with socket.io - in other words, how does socket.io get to know if the user is authenticated or not?

I welcome any comment or advice.

Thank you.

Community
  • 1
  • 1
SudoPlz
  • 20,996
  • 12
  • 82
  • 123

1 Answers1

4

First, I would use a different websocket library instead of socket.io. The socket.io developers are currently working on engine.io and socket.io appears to not be very actively maintained. I've experienced many of the issues described in the following links and since moving to sockjs have not had any problems.

http://www.quora.com/Sock-js/What-are-the-pros-and-cons-of-socket-io-vs-sockjs?share=1 https://github.com/LearnBoost/socket.io/issues https://github.com/ether/etherpad-lite/issues/1798 http://baudehlo.com/2013/05/07/sockjs-multiple-channels-and-why-i-dumped-socket-io/

You may have to implement your own custom events on top of sockjs, but that's pretty trivial. Since it sounds like you're already using redis then implementing rooms and pub/sub should be pretty easy too.

Here's how we do our token based socket authentication.

  1. First the client makes an HTTP request to the server to request a token. This routes the request through express' middleware and gives you easy access to the session data. This is where you would interact with passport to access their account or session data. If the user is logged in then generate a UUID and store their session data in redis as a key/value pair where the key is the UUID and the value is their stringified session/account data. Only send the UUID back to the client.
  2. When the client first creates a websocket connection set a flag on the socket that marks it as unauthenticated.
  3. When a message comes in on a socket check to see if the socket is authenticated. If not then check for a token in the message. If it doesn't exist then kill the connection. If it does then query redis for the key/value pair keyed by the token. If redis returns any data then you now have the session data for that user and can attach it to the socket and mark the socket as authenticated. If there's nothing in redis keyed by the token then kill the connection.

Now when you perform any operations on a socket you should have access to the session data for that user.

aembke
  • 2,479
  • 1
  • 15
  • 15
  • I've got a question though... The way you describe it, a websocket client ALWAYS gets connected. He only gets disconnected if his first message AFTER connection, contains a wrong token, or none at all. How can I pass a token through the first socket connection attempt (since sockJS does not support query). – SudoPlz Apr 29 '14 at 11:07
  • 1
    sockjs doesn't provide a way to kill the connection upon the http upgrade request. the above process prevents sockets from making any requests if they're not authenticated, but doesn't stop them from connecting. if you want to add some logic that perhaps marks the socket's initial connection time and cleans up unauthenticated sockets on an interval that might be one way to handle extra unauthenticated sockets hanging around. https://github.com/sockjs/sockjs-node#various-issues-and-design-considerations – aembke Apr 29 '14 at 20:29
  • 1
    If you'd like an easier way to handle this stuff our team just released the first version of a library designed to abstract away most of this stuff. Feel free to take a look. It still needs some work on the documentation but that should be cleaned up sometime in the next couple of weeks. https://github.com/azuqua/node-token-sockjs – aembke May 13 '14 at 20:37