I am wondering if this is the correct way to go about securing a socket.io room. Currently these are the steps that I am taking to ensure a user ends up in a private room, now I need to make sure the user gets authenticated before he is able to join.
- A client connects to my
socket.ioserver by callingio.connectand passing along the room he wants to join. - Client will be subscribed to the room and waits for emit of a message.
socket_writesends ajson_encodedobject to my server which holds a data property and the room to which this data will be sent.- My server receives the data through
socket.onand emits the data to the given room where the client is listening. - The client will receive the proper information meant for him only.
My client code:
var socket = io.connect('http://localhost:8000');
socket.on('connect', function() {
socket.emit('room', window.location.href);
});
The server:
const server = net.createServer((socket) => {
// The event that fires on PHP's socket_write.
socket.on('data', (msg) => {
const data = JSON.parse(msg);
io.sockets.in(data.room).emit('log', data.html.toString().trim());
});
}).listen(5600);
The on connection event of my server:
io.on('connection', function (socket) {
// A client will trigger this event and pass their window.location.href(room) as room identifier.
socket.on('room', function(room) {
socket.join(room);
});
});
How I write to my socket.io server:
$data = [
'html' => 'test',
'room' => 'http://app.dev/stephan-v/app-test'
];
$json = json_encode($data);
socket_write($this->socket, $json, strlen($json));
This is my implementation of a private websocket message but of course this is not secure. If somebody knows the name of the room that person could easily listen in on the emitted messages.
Since the socket.join can only take place on my server I guess the only place to authentication is at that point?
So instead of simply passing along the room I guess I should also pass in data to authenticate the user. And at that point make an AJAX requests from my node server to my PHP backend?
Obviously I do not want to send a plain password and username over the wire so I have been reading up on JSON web tokens. I guess you need to:
- send a JWT to the
nodeserver at the point of connection(along with which room to join, which I am currently doing). - Make an AJAX requests from my
node.jsserver to myPHPbackend on an authentication route. - Only let the user join the room if that user gets authenticated.
Sorry for the long post but there are a lot of components involved in this so I am hoping someone could confirm this workflow and perhaps give me some tips/pointers.
I would prefer not to install something like Redis at the moment because although it is a nice bridge between the frontend/backend it feels like overkill right now and I would like to understand this all at a more basic level.