Situation
I'm using the library SocketIO in my MEAN.JS application.
in NodeJS server controller:
var socketio = req.app.get('socketio');
socketio.sockets.emit('article.created.'+req.user._id, data);
in AngularJS client controller:
//Creating listener
Socket.on('article.created.'+Authentication.user._id, callback);
//Destroy Listener
$scope.$on('$destroy',function(){
Socket.removeListener('article.created.'+Authentication.user._id, callback);
});
Okey. Works well...
Problem
If a person (hacker or another) get the id of the user, he can create in another application a listener in the same channel and he can watch all the data that is sends to the user; for example all the notificacions...
How can I do the same thing but with more security?
Thanks!
Some time ago I stumbled upon the very same issue. Here's my solution (with minor modifications - used in production).
We will use Socket.IO
namespaces
to create private room for each user. Then we can emit messages (server-side) to specific rooms. In our case - only so specific user can receive them.But to create private room for each connected user, we have to verify their identify first. We'll use simple piece of authentication middleware for that, supported by Socket.IO since its 1.0 release.
1. Authentication middleware
Since its 1.0 release, Socket.IO supports middleware. We'll use it to:
jwt-simple
) he sent us as query parameter. (Note that this is just an example, there are many other ways to do this.)socket.io
connection instance, for later usage (in step 2).Server-side code example:
Here's example on how to provide token when initializing the connection, client-side:
2. Namespacing
Socket.io namespaces provide us with ability to create private room for each connected user. Then we can emit messages into specific room (so only users within it will receive them, as opposed to every connected client).
In previous step we made sure that:
socket.io
connection instance (socket.userId
).All that's left to do is joining proper room upon each connection, with name equal to user id of freshly connected client.
Now, we can emit targeted messages that only this user will receive: