I’ve been working on adding access control to a y-websocket server using our existing cookie-based sessions on an express node.js server. I want to sanity-check what I’ve come up with to make sure it all makes sense.
I’m having the client add the yDoc clientID as a query param on the Websocket URL (e.g. /roomname?clientID=1234567). That allows the server to try to “lock” a clientID to the current session’s user before accepting the connection. Only one userId can be associated with a given clientID in a room, so if another user tries to “lock” a clientID that has already been “locked”, then the connection will be rejected. My reasoning is that once a the websocket server broadcasts a clientID either via awareness or a sync, then any client could try to hijack that clientID. On the server-side of the connection, the clientID in the awareness/sync messages MUST match the clientID or the message will be rejected. Does this make sense?
I’m using the following to extract the clientIDs in each message
awareness: A modified version of https://github.com/yjs/y-protocols/blob/master/awareness.js#L194 to just return the clientIDs
I also am using
modifyAwarenessUpdate from https://github.com/yjs/y-protocols/blob/master/awareness.js#L219 right before here: https://github.com/yjs/y-websocket/blob/master/bin/utils.js#L177 to change the
user parameter in the awareness message, because the server (not the client) should only be trusted to fill in that current user information.
Storing the user associated with a clientID on the server is also really nice to be able to build accurate history like Google Docs without having to rely on Y.PermanentUserData, which can be modified on the client-side.