Blog | G5 Cyber Security

JWT Authentication in WebSockets

TL;DR

This guide shows you how to secure your WebSocket connections using JWT (JSON Web Tokens). We’ll cover verifying the token on connection and handling invalid tokens. It assumes you already have a system for issuing JWTs.

Steps

  1. Server-Side Setup: Receive Token
const ws = new WebSocket.Server({ port: 8080 });

ws.on('connection', ws => {
  const urlParams = new URLSearchParams(ws.upgradeReq.url);
  const token = urlParams.get('token');
  // ... further processing
});
  • Token Verification
  • const jwt = require('jsonwebtoken');
    
    ws.on('connection', ws => {
      const urlParams = new URLSearchParams(ws.upgradeReq.url);
      const token = urlParams.get('token');
    
      jwt.verify(token, 'your-secret-key', (err, decoded) => {
        if (err) {
          // Token is invalid
          console.error('Invalid token:', err.message);
          ws.send(JSON.stringify({ type: 'auth_failed', message: 'Invalid token' }));
          ws.terminate(); // Close the connection
          return;
        }
    
        // Token is valid, decoded contains user information
        console.log('Decoded token:', decoded);
        // ... proceed with authenticated connection
      });
    });
  • Important: Replace 'your-secret-key' with your actual secret key used to sign the JWTs. Keep this key secure!
  • Handle Invalid Tokens
  • Authenticated Connection Handling
  • const connectedUsers = new Map(); // ws object -> user data
    
    ws.on('connection', ws => {
      // ... token verification...
    
      connectedUsers.set(ws, decoded);
    });
  • Message Handling & Authorization
  • ws.on('message', message => {
      const userData = connectedUsers.get(ws);
      if (!userData) {
        // User is not authenticated (connection likely lost)
        console.error('Unauthorized access');
        return;
      }
    
      // Check user permissions based on userData...
    });
  • Connection Closure
  • ws.on('close', () => {
      connectedUsers.delete(ws);
    });

    Security Considerations

    Exit mobile version