{"id":16680,"library":"sc-auth","title":"SocketCluster Authentication Module","description":"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.","status":"maintenance","version":"6.0.0","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","Auth","SocketCluster","JWT"],"install":[{"cmd":"npm install sc-auth","lang":"bash","label":"npm"},{"cmd":"yarn add sc-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add sc-auth","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for JWT signing and verification.","package":"jsonwebtoken","optional":false}],"imports":[{"note":"The package primarily exports via CommonJS `module.exports`. For ESM, consider a dynamic import or a CommonJS wrapper.","wrong":"import { AuthEngine } from 'sc-auth';","symbol":"AuthEngine","correct":"const AuthEngine = require('sc-auth').AuthEngine;"},{"note":"An alternative export for creating the engine. Typically, you'd directly instantiate AuthEngine.","symbol":"createAuthEngine","correct":"const { createAuthEngine } = require('sc-auth');"},{"note":"While AuthEngine has signToken, a top-level signToken utility may also be exposed (requires checking specific `index.js` for confirmation). The primary usage pattern is via an AuthEngine instance.","symbol":"signToken","correct":"const { signToken } = require('sc-auth');"}],"quickstart":{"code":"const http = require('http');\nconst socketClusterServer = require('socketcluster-server');\nconst { AuthEngine } = require('sc-auth');\n\nconst AUTH_KEY = process.env.AUTH_SIGNATURE_KEY ?? 'my-secret-auth-key'; // NEVER hardcode in production!\nconst TOKEN_EXPIRY_IN_SECONDS = 3600; // 1 hour\n\nconst httpServer = http.createServer();\nconst authEngine = new AuthEngine(AUTH_KEY, {\n  algorithm: 'HS256', // Default algorithm\n  expiresIn: TOKEN_EXPIRY_IN_SECONDS\n});\n\nconst agServer = socketClusterServer.attach(httpServer, {\n  authKey: AUTH_KEY,\n  authEngine: authEngine // Inject sc-auth's engine\n});\n\n(async () => {\n  for await (let { socket } of agServer.listener('connection')) {\n    // Example of authenticating a socket after a login event\n    socket.on('login', async (credentials, respond) => {\n      if (credentials.username === 'user' && credentials.password === 'pass') {\n        const tokenData = { username: credentials.username, role: 'admin' };\n        try {\n          const token = await authEngine.signToken(tokenData);\n          socket.authenticate(token);\n          respond(); // Acknowledge successful login\n        } catch (error) {\n          respond(error); // Send error back to client\n        }\n      } else {\n        respond(new Error('Invalid credentials'));\n      }\n    });\n\n    // Example middleware to check authenticated status\n    agServer.setMiddleware(agServer.MIDDLEWARE_INBOUND, async (middlewareStream) => {\n      for await (let action of middlewareStream) {\n        if (action.type === action.PUBLISH_IN) {\n          if (!action.socket.authToken) {\n            action.block(new Error('Authentication required to publish.'));\n            continue;\n          }\n          // Further authorization checks based on action.socket.authToken.role\n          if (action.socket.authToken.role !== 'admin' && action.channel === 'adminChannel') {\n            action.block(new Error('Not authorized for this channel.'));\n            continue;\n          }\n        }\n        action.next();\n      }\n    });\n  }\n})();\n\nhttpServer.listen(8000, () => {\n  console.log(`SocketCluster server listening on port 8000`);\n});\n","lang":"javascript","description":"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."},"warnings":[{"fix":"Refactor asynchronous calls using `await` or `.then()` to handle Promises instead of traditional Node.js callbacks.","message":"Version 6.0.0 of `sc-auth` (and SocketCluster v15+) introduced a breaking change by transitioning from callback-based functions to Promise-based asynchronous operations. Code expecting callbacks will fail.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Evaluate whether direct use of the `jsonwebtoken` package or SocketCluster's `agServer.auth` methods are more suitable for new projects or if this package's functionalities can be safely migrated. Regularly audit dependencies for vulnerabilities.","message":"The `sc-auth` package has not seen active development in approximately eight years (as of 2026), with its last published version (6.0.0) dating back to then. While functional, it may lack modern features, security updates, or compatibility fixes for newer Node.js versions or evolving JWT standards.","severity":"gotcha","affected_versions":">=6.0.0"},{"fix":"Always store the `authKey` in environment variables (e.g., `process.env.AUTH_SIGNATURE_KEY`) or a secure configuration management system. Ensure it is a long, cryptographically strong random string.","message":"The `authKey` (or signature key) used to sign and verify JWTs is critical for security. Hardcoding it, using a weak key, or exposing it publicly severely compromises the integrity of your authentication system.","severity":"gotcha","affected_versions":"*"},{"fix":"Only include non-sensitive information necessary for authorization (e.g., user ID, roles, permissions) in the JWT payload. Fetch sensitive user data from a secure backend store (e.g., database) after token verification.","message":"JWTs, by design, are signed but not encrypted. Sensitive user data should never be stored directly in the JWT payload, as it can be read by anyone with the token.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Implement client-side logic to detect expired tokens and automatically request a new one (e.g., using a refresh token mechanism) or prompt the user to re-authenticate. Ensure server-side logic handles `TokenExpiredError` gracefully.","cause":"The provided JWT has passed its expiry time, making it invalid for use.","error":"TokenExpiredError: jwt expired"},{"fix":"Verify that the same `authKey` (or signature key) is consistently used across all signing and verification points in your application. Ensure no part of the token was altered after signing. This often happens if an `authKey` is mismatched between different services or deployments.","cause":"The JWT's signature does not match, indicating the token was tampered with or signed with a different secret key than the one used for verification.","error":"JsonWebTokenError: invalid signature"},{"fix":"For CommonJS, use `const AuthEngine = require('sc-auth').AuthEngine;`. If using ESM, `sc-auth` might not natively support it for direct named imports; consider `const { AuthEngine } = await import('sc-auth');` or wrapping it in a CommonJS file that exports an ESM-compatible module.","cause":"Attempting to import `AuthEngine` using an incorrect syntax (e.g., CommonJS `require` in an ESM context, or an incorrect named import).","error":"TypeError: AuthEngine is not a constructor"},{"fix":"Ensure the `AuthEngine` is initialized with the correct `authKey` (e.g., `new AuthEngine(process.env.AUTH_SIGNATURE_KEY)`). Double-check environment variable loading and configuration.","cause":"The `authKey` (or a corresponding public/private key pair) was not provided to the `AuthEngine` constructor or the `verifyToken` method.","error":"Error: Missing credentials for token verification"}],"ecosystem":"npm"}