Course contentsShow
← Node.js
Lesson 1076 of 1,98010. Real-time Communication and WebsocketsFree lesson

Managing Client Metadata with Persistent Sessions

You will associate WebSocket connections with specific user accounts using authentication middleware.

In this lesson, you will learn how to bridge the gap between stateless authentication tokens and stateful WebSocket connections by attaching user identity directly to the connection object.

When a client initiates a WebSocket connection, they typically send an Authorization header or a query string token during the initial HTTP handshake. Because WebSockets upgrade from a standard HTTP request, we can intercept this handshake to authenticate the user before the connection is ever established. By validating the user's session metadata at this precise moment, we can "stamp" the persistent WebSocket object with the user's identity.

Attaching Metadata to the Connection

Once the handshake is verified, you should store the user's unique identifier or their permission scope directly on the socket object. This ensures that every subsequent message sent over that connection carries the user's context, preventing the need to re-verify identity for every single packet.

Here is how you might associate the identity during the connection event:

const wss = new WebSocket.Server({ noServer: true });

server.on('upgrade', (request, socket, head) => {
  // Use your existing auth verification logic here
  const user = verifyToken(request.headers['sec-websocket-protocol']);
  
  if (!user) {
    socket.destroy();
    return;
  }

  wss.handleUpgrade(request, socket, head, (ws) => {
    // Attach the identity context to the connection object
    ws.user = { id: user.id, roles: user.roles };
    wss.emit('connection', ws, request);
  });
});

wss.on('connection', (ws) => {
  ws.on('message', (data) => {
    // Now you have immediate access to the authenticated user's metadata
    console.log(`Message received from user ${ws.user.id}`);
  });
});

By binding the user object to ws, you treat the WebSocket as a "persistent session." This allows your message handlers to be context-aware, ensuring that sensitive data is only processed if the user metadata attached to the specific socket possesses the required access scopes. Because this metadata is set at the start, you avoid repetitive, expensive database lookups while maintaining tight control over who is sending data through your real-time pipes.

Key Takeaway: Associate user identity with the WebSocket object during the handshake to create a persistent, context-aware session that simplifies authorization for all subsequent real-time messages.