Socket.IO enables real-time bidirectional event-based communication.
Socket.IO uses web sockets for communication between the Node.js server and its clients. If client emits an event with some data, server can listen to it and use the data, and vice versa. The server can also broadcast events to all clients. In this article, we will see how to use our site’s sessions for authentication with Socket.IO.
The entire code for the application can be found here and the working demo is deployed here. We have a small chat application. When a new user opens the application, he gets a session with a random number as his user id
. This is required by Socket.IO for authentication.
The Basic App
We start with a simple chat application made in Node.js with Koa web framework. The code at this point can be found at the before-session
tag of the code repository here.
The server file, index.js
creates a Koa server and serves a static folder public
which contains a HTML page and a javascript file. It then connects this server to Socket.IO. The code looks like this.
The client, public/app.js
connects to Socket.IO and sends the chat message to server by emitting send chat
event and listens for new chat
event for any new messages from other users. Note that we are only sending the message to the server and nothing about the user.
Adding Sessions
To add session authentication to Socket.IO, we only need to make the change in the server side code. That is the index.js
file. First, we need to install two modules, koa-session
and cookie
.
Require these from index.js
page and set up koa-session
with some secret key.
Now, we’ll create a session for all users with some random number as the username. However, we only need to create a new session if one doesn’t already exist. This way, a user will have the same username even if he closes the app and reopens it. Also, we need to put all these middleware functions before serving the public folder.
koa-session
will generate two cookies, koa:sess
and koa:sess.sig
. We are interested in koa:sess
. It contains all the data we put in to the session and some default values in base64 encoded
format. After decoding, it will contain something like this.
Now, we can get to Socket.IO authorization. You can define custom authorization for Socket.IO with this function.
Only if we send accept(null, true);
, the web-socket handshake happens and we can communicate with it.
Here, we need to parse the cookies, which is available in data.headers.cookie
to obtain koa:sess
cookie. We then decode it and extract name
from it. We will store this in data.name
. We will only allow connections if the cookie exists with a name
.
If you are using some sort of session store with a database. You can get the user data required by quering the database with the cookie.
Now, the name
that we added to data object during authorization can be accessed from socket.request.name
. So, we can modify the send chat
event listener to include the user ID.
That’s all we need to do to incorporate our sessions to Socket.IO. The complete server side code now looks like this.
Conclusion
In this article, we have seen how to use sessions to authenticate user while connecting to Socket.IO. This enables us to provide security for data communication with web sockets and store the user data persistently.