DEV Community

Young Gao
Young Gao

Posted on

WebSocket Authentication: Securing Real-Time Connections

WebSocket Authentication: Securing Real-Time Connections

Your WebSocket server accepts any connection. Anyone can subscribe to private channels. Here is how to authenticate WebSocket connections properly.

Token-Based Authentication

import { WebSocketServer } from "ws";
import jwt from "jsonwebtoken";

const wss = new WebSocketServer({ noServer: true });

server.on("upgrade", (req, socket, head) => {
  // Extract token from query string or header
  const url = new URL(req.url, "http://localhost");
  const token = url.searchParams.get("token");

  if (\!token) {
    socket.write("HTTP/1.1 401 Unauthorized

");
    socket.destroy();
    return;
  }

  try {
    const user = jwt.verify(token, process.env.JWT_SECRET);
    wss.handleUpgrade(req, socket, head, (ws) => {
      ws.user = user;
      wss.emit("connection", ws, req);
    });
  } catch {
    socket.write("HTTP/1.1 401 Unauthorized

");
    socket.destroy();
  }
});
Enter fullscreen mode Exit fullscreen mode

Channel Authorization

wss.on("connection", (ws) => {
  ws.on("message", (data) => {
    const msg = JSON.parse(data.toString());
    if (msg.type === "subscribe") {
      if (\!canAccess(ws.user, msg.channel)) {
        ws.send(JSON.stringify({ error: "Forbidden" }));
        return;
      }
      channels.get(msg.channel)?.add(ws);
    }
  });
});
Enter fullscreen mode Exit fullscreen mode

Security Checklist

  • Authenticate on the upgrade request, not after connection
  • Use short-lived tokens (avoid long-lived session cookies)
  • Implement heartbeat/ping to detect stale connections
  • Rate limit message frequency per client
  • Validate and sanitize all incoming messages

Part of my Production Backend Patterns series. Follow for more practical backend engineering.

Top comments (0)