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