SocketCluster Authentication Module

6.0.0 · maintenance · verified Wed Apr 22

sc-auth is a foundational authentication module specifically designed for the SocketCluster real-time framework. It facilitates JSON Web Token (JWT) based authentication, which is the default mechanism in SocketCluster. This package, currently at version 6.0.0 (released approximately eight years ago), handles the core logic for signing and verifying JWTs within a SocketCluster environment. While newer SocketCluster documentation often guides developers towards using `agServer.auth.signToken` or `jsonwebtoken` directly, `sc-auth` provides a structured `AuthEngine` for this purpose. Its primary role is to enable persistent user sessions, cross-browser tab authentication, and secure access control by signing arbitrary data objects with a secret key. Due to its age, developers should be aware that active development is minimal, and practices may have evolved in the broader SocketCluster ecosystem. Its release cadence is effectively dormant, with its last major update occurring many years ago.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to integrate `sc-auth` with a SocketCluster server to handle JWT-based authentication. It shows initializing the `AuthEngine`, using it to sign tokens upon a 'login' event, and implementing inbound middleware to verify token presence and perform basic role-based authorization for publishing to channels.

const http = require('http');
const socketClusterServer = require('socketcluster-server');
const { AuthEngine } = require('sc-auth');

const AUTH_KEY = process.env.AUTH_SIGNATURE_KEY ?? 'my-secret-auth-key'; // NEVER hardcode in production!
const TOKEN_EXPIRY_IN_SECONDS = 3600; // 1 hour

const httpServer = http.createServer();
const authEngine = new AuthEngine(AUTH_KEY, {
  algorithm: 'HS256', // Default algorithm
  expiresIn: TOKEN_EXPIRY_IN_SECONDS
});

const agServer = socketClusterServer.attach(httpServer, {
  authKey: AUTH_KEY,
  authEngine: authEngine // Inject sc-auth's engine
});

(async () => {
  for await (let { socket } of agServer.listener('connection')) {
    // Example of authenticating a socket after a login event
    socket.on('login', async (credentials, respond) => {
      if (credentials.username === 'user' && credentials.password === 'pass') {
        const tokenData = { username: credentials.username, role: 'admin' };
        try {
          const token = await authEngine.signToken(tokenData);
          socket.authenticate(token);
          respond(); // Acknowledge successful login
        } catch (error) {
          respond(error); // Send error back to client
        }
      } else {
        respond(new Error('Invalid credentials'));
      }
    });

    // Example middleware to check authenticated status
    agServer.setMiddleware(agServer.MIDDLEWARE_INBOUND, async (middlewareStream) => {
      for await (let action of middlewareStream) {
        if (action.type === action.PUBLISH_IN) {
          if (!action.socket.authToken) {
            action.block(new Error('Authentication required to publish.'));
            continue;
          }
          // Further authorization checks based on action.socket.authToken.role
          if (action.socket.authToken.role !== 'admin' && action.channel === 'adminChannel') {
            action.block(new Error('Not authorized for this channel.'));
            continue;
          }
        }
        action.next();
      }
    });
  }
})();

httpServer.listen(8000, () => {
  console.log(`SocketCluster server listening on port 8000`);
});

view raw JSON →