Quick Tip: Node.js + Socket.io + Authentication

Introduction

This is an incredibly quick tip that might save you a ton of time. I hope this tip receives you well.

Problem

Socket.IO does not have access to session information, therefore the server has no way of linking a message it receives to a specific user.

Solution

If you are running into this situation the solution is to use cookies. When you authenticate your user in your main application, create a cookie with the information you’d like socket to know. The user ID is a good start. Then send the cookie to the client. In express you can do this with res.cookie(key, value); . Then you can pull in this information with javascript on the client-side using document.cookie. Now the client has a userID that he can pass within a socket.io message to the server for the remainder of the session. I sincerely believe this is the only way. I’m pretty sure I’ve tried every iteration possible, leading to all sorts of race conditions. I dare you to come up with another solution . As always, feedback is appreciated!

Comments

Dan

Thursday, January 20th, 2011

Do you have to do your authenticating via node.js?

Matt Mueller

Saturday, January 22nd, 2011

No, you can authenticate using other architectures, this problem is unique to node.js because of node's asynchronous nature that causes race conditions between the socket.io connection and session authentication.

Sam Lown    •   https://www.samlown.com

Thursday, August 4th, 2011

This strikes me as a tad in-secure from the outset. Unless you're sending a password provided by the client to the socket with the user ID and authorizing again, it would be pretty trivial to set a breakpoint in your browser and put in a different user ID. The socket wouldn't know any better. (I guess this is called socket hijacking?). Ruby on Rails for example gets around this problem by hashing (SHA512) the session information using a secret key on the server. This way we know that the user id hasn't been tampered with. (Unless your code has been stolen ;-) Cheers, sam

Andreas    •   https://www.andreasklostermann.de/

Monday, December 19th, 2011

I'd suggest you submit the sessionid by cookie (or in the template context and put it into the dom which avoids any cookie hassles). Then (client-side) on connection, you can emit the sessionid. Serverside the connection listens and does normal session-id authentication. It might drop the connection if the session id is invalid. For some functions it will be easiest to sidestep socket.io, and just implement the "authenticated" part of the api as get/post requests. And if that doesn't work you should probably not be using socket.io and just implement a socket on your own, which is not that difficult either.