New protocol version released : This page may contain outdated information.
 
The HAIP Server uses JWT (JSON Web Tokens) for authentication, providing secure, stateless authentication for all client connections. 
JWT Authentication Secure token-based authentication 
Session Management Per-client session tracking and management 
Token Validation Automatic token validation and expiry checking 
User Identification Extract user information from tokens 
 
JWT Configuration  
Basic Configuration  
const  server  =  new  HAIPServer ({  
  jwtSecret:  "your-secret-key-here" ,  
  jwtExpiresIn:  "24h" ,  
});  
 
Environment Variables  
# Required: JWT secret for signing tokens  
JWT_SECRET = your-secret-key-here  
 
# Optional: Token expiration time (default: 24h)  
JWT_EXPIRES_IN = 24h  
 
Security Best Practices  
// Production configuration  
const  secureConfig  =  {  
  jwtSecret:  process . env . JWT_SECRET ,  // Use environment variable  
  jwtExpiresIn:  "1h" ,  // Short expiration for security  
  enableCORS:  false ,  // Disable CORS in production  
  enableLogging:  true ,  
};  
 
Token Structure  
JWT Payload  
{  
  "userId" :  "user-123" ,  
  "iat" :  1634567890 ,  
  "exp" :  1634654290 ,  
  "iss" :  "haip-server" ,  
  "aud" :  "haip-client"  
}  
 
Required Claims  
userId : Unique identifier for the user 
iat : Issued at timestamp 
exp : Expiration timestamp 
 
Optional Claims  
iss : Issuer (default: “haip-server”) 
aud : Audience (default: “haip-client”) 
sub : Subject (user ID) 
jti : JWT ID (unique identifier) 
 
Client Authentication  
WebSocket Authentication  
// Connect with JWT token  
const  token  =  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ;  
const  ws  =  new  WebSocket ( `ws://localhost:8080/haip/websocket?token= ${ token } ` );  
 
ws . on ( "open" , ()  =>  {  
  console . log ( "Authenticated WebSocket connection" );  
});  
 
ws . on ( "error" , ( error )  =>  {  
  console . error ( "Authentication failed:" ,  error );  
});  
 
SSE Authentication  
// Connect with JWT token  
const  token  =  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ;  
const  eventSource  =  new  EventSource (  
  `http://localhost:8080/haip/sse?token= ${ token } `  
);  
 
eventSource . onopen  =  ()  =>  {  
  console . log ( "Authenticated SSE connection" );  
};  
 
eventSource . onerror  =  ( error )  =>  {  
  console . error ( "Authentication failed:" ,  error );  
};  
 
HTTP Streaming Authentication  
// Connect with JWT token in Authorization header  
const  token  =  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ;  
 
const  response  =  await  fetch ( "http://localhost:8080/haip/stream" , {  
  method:  "POST" ,  
  headers:  {  
    Authorization:  `Bearer  ${ token } ` ,  
    "Content-Type" :  "application/json" ,  
  },  
  body:  JSON . stringify ( handshakeMessage ),  
});  
 
if  ( response . ok ) {  
  console . log ( "Authenticated HTTP streaming connection" );  
}  else  {  
  console . error ( "Authentication failed:" ,  response . status );  
}  
 
Token Generation  
Server-Side Token Generation  
import  jwt  from  "jsonwebtoken" ;  
 
// Generate JWT token  
function  generateToken (  
  userId :  string ,  
  secret :  string ,  
  expiresIn :  string  =  "24h"  
) {  
  const  payload  =  {  
    userId ,  
    iat:  Math . floor ( Date . now ()  /  1000 ),  
    iss:  "haip-server" ,  
    aud:  "haip-client" ,  
  };  
 
  return  jwt . sign ( payload ,  secret , {  expiresIn  });  
}  
 
// Example usage  
const  token  =  generateToken ( "user-123" ,  process . env . JWT_SECRET ,  "1h" );  
console . log ( "Generated token:" ,  token );  
 
Token Validation  
import  jwt  from  "jsonwebtoken" ;  
 
// Validate JWT token  
function  validateToken ( token :  string ,  secret :  string ) {  
  try  {  
    const  decoded  =  jwt . verify ( token ,  secret );  
    return  {  
      valid:  true ,  
      payload:  decoded ,  
    };  
  }  catch  ( error ) {  
    return  {  
      valid:  false ,  
      error:  error . message ,  
    };  
  }  
}  
 
// Example usage  
const  result  =  validateToken ( token ,  process . env . JWT_SECRET );  
if  ( result . valid ) {  
  console . log ( "Valid token for user:" ,  result . payload . userId );  
}  else  {  
  console . error ( "Invalid token:" ,  result . error );  
}  
 
Session Management  
Session Creation  
When a client connects with a valid token, the server automatically creates a session: 
// Session is created automatically  
const  session  =  {  
  id:  "session-uuid" ,  
  userId:  "user-123" ,  
  connected:  true ,  
  handshakeCompleted:  false ,  
  lastActivity:  Date . now (),  
  credits:  new  Map ([  
    [ "USER" ,  1000 ],  
    [ "AGENT" ,  1000 ],  
    [ "SYSTEM" ,  1000 ],  
  ]),  
  // ... other session properties  
};  
 
Session Tracking  
// Get session information  
const  session  =  server . getSession ( "session-id" );  
if  ( session ) {  
  console . log ( "Session user:" ,  session . userId );  
  console . log ( "Session connected:" ,  session . connected );  
  console . log ( "Last activity:" ,  session . lastActivity );  
}  
 
Session Cleanup  
Sessions are automatically cleaned up when clients disconnect: 
// Session cleanup happens automatically  
server . on ( "disconnect" , ( sessionId )  =>  {  
  console . log ( "Session disconnected:" ,  sessionId );  
  // Session is automatically removed from memory  
});  
 
Error Handling  
Authentication Errors  
// Invalid token  
{  
  "type" :  "ERROR" ,  
  "channel" :  "SYSTEM" ,  
  "payload" : {  
    "code" :  "INVALID_TOKEN" ,  
    "message" :  "Invalid or expired JWT token"  
  }  
}  
 
// Missing token  
{  
  "type" :  "ERROR" ,  
  "channel" :  "SYSTEM" ,  
  "payload" : {  
    "code" :  "MISSING_TOKEN" ,  
    "message" :  "JWT token is required"  
  }  
}  
 
// Expired token  
{  
  "type" :  "ERROR" ,  
  "channel" :  "SYSTEM" ,  
  "payload" : {  
    "code" :  "TOKEN_EXPIRED" ,  
    "message" :  "JWT token has expired"  
  }  
}  
 
Client-Side Error Handling  
// Handle authentication errors  
ws . on ( "message" , ( data )  =>  {  
  const  message  =  JSON . parse ( data . toString ());  
 
  if  ( message . type  ===  "ERROR" ) {  
    switch  ( message . payload . code ) {  
      case  "INVALID_TOKEN" :  
        console . error ( "Invalid token, please re-authenticate" );  
        // Redirect to login or refresh token  
        break ;  
      case  "TOKEN_EXPIRED" :  
        console . error ( "Token expired, please refresh" );  
        // Refresh token or redirect to login  
        break ;  
      case  "MISSING_TOKEN" :  
        console . error ( "No token provided" );  
        // Redirect to login  
        break ;  
    }  
  }  
});  
 
Token Refresh  
Client-Side Token Refresh  
class  HAIPClient  {  
  constructor ( url ,  token ,  refreshToken ) {  
    this . url  =  url ;  
    this . token  =  token ;  
    this . refreshToken  =  refreshToken ;  
    this . ws  =  null ;  
  }  
 
  async  refreshToken () {  
    try  {  
      const  response  =  await  fetch ( "/auth/refresh" , {  
        method:  "POST" ,  
        headers:  {  
          "Content-Type" :  "application/json" ,  
        },  
        body:  JSON . stringify ({  
          refreshToken:  this . refreshToken ,  
        }),  
      });  
 
      if  ( response . ok ) {  
        const  data  =  await  response . json ();  
        this . token  =  data . token ;  
        this . refreshToken  =  data . refreshToken ;  
        return  true ;  
      }  
    }  catch  ( error ) {  
      console . error ( "Token refresh failed:" ,  error );  
    }  
    return  false ;  
  }  
 
  async  connect () {  
    // Try to connect with current token  
    this . ws  =  new  WebSocket ( ` ${ this . url } ?token= ${ this . token } ` );  
 
    this . ws . onerror  =  async  ( error )  =>  {  
      // If authentication fails, try to refresh token  
      if  ( await  this . refreshToken ()) {  
        // Reconnect with new token  
        this . connect ();  
      }  else  {  
        // Redirect to login  
        window . location . href  =  "/login" ;  
      }  
    };  
  }  
}  
 
Security Considerations  
1. Secure Token Storage  
// Client-side secure storage  
class  TokenManager  {  
  static  setToken ( token ) {  
    // Store in memory for session duration  
    sessionStorage . setItem ( "haip_token" ,  token );  
  }  
 
  static  getToken () {  
    return  sessionStorage . getItem ( "haip_token" );  
  }  
 
  static  clearToken () {  
    sessionStorage . removeItem ( "haip_token" );  
  }  
}  
 
2. Token Rotation  
// Server-side token rotation  
class  TokenService  {  
  static  async  rotateToken ( oldToken :  string ,  secret :  string ) {  
    const  decoded  =  jwt . verify ( oldToken ,  secret );  
 
    // Generate new token with same user  
    const  newToken  =  jwt . sign (  
      {  
        userId:  decoded . userId ,  
        iat:  Math . floor ( Date . now ()  /  1000 ),  
        iss:  "haip-server" ,  
        aud:  "haip-client" ,  
      },  
      secret ,  
      {  expiresIn:  "1h"  }  
    );  
 
    return  newToken ;  
  }  
}  
 
3. Rate Limiting  
// Implement rate limiting for authentication  
import  rateLimit  from  "express-rate-limit" ;  
 
const  authLimiter  =  rateLimit ({  
  windowMs:  15  *  60  *  1000 ,  // 15 minutes  
  max:  5 ,  // limit each IP to 5 requests per windowMs  
  message:  "Too many authentication attempts" ,  
});  
 
app . use ( "/auth" ,  authLimiter );  
 
4. HTTPS in Production  
// Always use HTTPS in production  
const  productionConfig  =  {  
  // ... other config  
  ssl:  {  
    enabled:  true ,  
    cert:  process . env . SSL_CERT ,  
    key:  process . env . SSL_KEY ,  
  },  
};  
 
Monitoring and Logging  
Authentication Events  
// Listen for authentication events  
server . on ( "connect" , ( sessionId )  =>  {  
  const  session  =  server . getSession ( sessionId );  
  console . log ( `User  ${ session ?. userId }  connected with session  ${ sessionId } ` );  
});  
 
server . on ( "disconnect" , ( sessionId )  =>  {  
  const  session  =  server . getSession ( sessionId );  
  console . log ( `User  ${ session ?. userId }  disconnected from session  ${ sessionId } ` );  
});  
 
Authentication Statistics  
// Get authentication statistics  
const  stats  =  server . getStats ();  
console . log ( "Active sessions:" ,  stats . activeConnections );  
console . log ( "Total connections:" ,  stats . totalConnections );  
 
Testing Authentication  
Generate Test Tokens  
// Generate test tokens for development  
function  generateTestToken ( userId :  string  =  "test-user" ) {  
  const  payload  =  {  
    userId ,  
    iat:  Math . floor ( Date . now ()  /  1000 ),  
    exp:  Math . floor ( Date . now ()  /  1000 )  +  3600 ,  // 1 hour  
    iss:  "haip-server" ,  
    aud:  "haip-client" ,  
  };  
 
  return  jwt . sign ( payload ,  "test-secret-key" );  
}  
 
// Usage  
const  testToken  =  generateTestToken ( "test-user-123" );  
console . log ( "Test token:" ,  testToken );  
 
Test Authentication  
// Test authentication with generated token  
const  testToken  =  generateTestToken ( "test-user" );  
const  ws  =  new  WebSocket (  
  `ws://localhost:8080/haip/websocket?token= ${ testToken } `  
);  
 
ws . on ( "open" , ()  =>  {  
  console . log ( "✅ Authentication test passed" );  
  ws . close ();  
});  
 
ws . on ( "error" , ( error )  =>  {  
  console . error ( "❌ Authentication test failed:" ,  error );  
});  
 
Next Steps