0PricingLogin
NestJS Enterprise Backend APIs · Lesson

Authenticating and Guarding Socket Connections

Apply guards and token verification to handshake and message events for secure realtime access.

Why Sockets Need Their Own Auth Story

HTTP routes in NestJS are protected by middleware and guards that read the Authorization header on every request. WebSockets are different: the client opens one long-lived connection during the handshake, then exchanges many messages over it.

  • You authenticate once at connection time, not per message.
  • The socket stays open for minutes or hours, so a token that expires mid-session is a real concern.
  • Standard HTTP guards do not automatically run on WebSocket events.

This lesson shows how to verify a token during the handshake, attach the user to the socket, and guard individual message events for secure realtime access.

Where the Token Lives in a Handshake

A browser WebSocket cannot set custom headers, so clients pass the token in one of three places during the Socket.IO handshake:

  • handshake.auth.token — the modern, preferred slot (set via the client auth option).
  • handshake.headers.authorization — works when a native header is available.
  • handshake.query.token — a fallback, but tokens land in server/proxy logs, so avoid it.

A small helper centralizes extraction so every guard and lifecycle hook reads the token the same way.

import { Socket } from 'socket.io';

export function extractToken(client: Socket): string | null {
  const auth = client.handshake.auth?.token;
  if (typeof auth === 'string') return auth;

  const header = client.handshake.headers?.authorization;
  if (typeof header === 'string' && header.startsWith('Bearer ')) {
    return header.slice(7);
  }

  return null;
}

All lessons in this course

  1. WebSocket Gateways with the Socket.IO Adapter
  2. Authenticating and Guarding Socket Connections
  3. Server-Sent Events for One-Way Push
  4. Scaling Realtime with a Redis Pub/Sub Adapter
← Back to NestJS Enterprise Backend APIs