0

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.

  1. A client connects to my socket.io server by calling io.connect and passing along the room he wants to join.
  2. Client will be subscribed to the room and waits for emit of a message.
  3. socket_write sends a json_encoded object to my server which holds a data property and the room to which this data will be sent.
  4. My server receives the data through socket.on and emits the data to the given room where the client is listening.
  5. 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:

  1. send a JWT to the node server at the point of connection(along with which room to join, which I am currently doing).
  2. Make an AJAX requests from my node.js server to my PHP backend on an authentication route.
  3. 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.

Stephan-v
  • 19,255
  • 31
  • 115
  • 201
  • Possible duplicate of [How do I secure Socket.IO?](https://stackoverflow.com/questions/11519777/how-do-i-secure-socket-io) – David R Sep 14 '17 at 13:23
  • The main accepted answer there is to install Redis to deal with this, which feels like major overkill to me. I do not want to have yet another service and I do not currently need to scale this up. I am hoping to keep this basic and at the moment clear of dedicated packages. For simplicity and to learn how this all works exactly. – Stephan-v Sep 14 '17 at 13:27
  • 1
    Sorry Steve. Since I didn't see that in your post, I have raised the flag.. You have edited it now though!. Thanks – David R Sep 14 '17 at 13:29

0 Answers0