Authentication overview
Authentication overview
Section titled “Authentication overview”Jetsocket.io provides several authentication mechanisms to secure your real-time applications and protect sensitive data.
Authentication Types
Section titled “Authentication Types”Channel Authorization
Section titled “Channel Authorization”Channel authorization is used for private and presence channels. It ensures that only authorized users can subscribe to specific channels.
// Client-sideconst channel = jetsocket.subscribe("private-my-channel");
// Server-side authorization endpointapp.post("/jetsocket/auth", (req, res) => { const socketId = req.body.socket_id; const channel = req.body.channel_name;
if (canAccessChannel(req.user, channel)) { const authResponse = jetsocket.authorizeChannel(socketId, channel); res.send(authResponse); } else { res.status(403).send("Forbidden"); }});User Authentication
Section titled “User Authentication”User authentication allows you to identify users across all their connections and send them targeted messages.
// Client-sidejetsocket.signin();
// Server-side authentication endpointapp.post("/jetsocket/user-auth", (req, res) => { const socketId = req.body.socket_id; const user = req.user;
const authResponse = jetsocket.authenticateUser(socketId, { user_id: user.id, user_info: { name: user.name, email: user.email } });
res.send(authResponse);});Security Features
Section titled “Security Features”TLS Encryption
Section titled “TLS Encryption”All connections to Jetsocket.io are encrypted using TLS by default. This ensures that all data transmitted between your application and Jetsocket.io is secure.
const jetsocket = new Jetsocket("APP_KEY", { cluster: "APP_CLUSTER", forceTLS: true, // Default: true});Encrypted Channels
Section titled “Encrypted Channels”For additional security, you can use encrypted channels that provide end-to-end encryption for sensitive data.
// Client-sideconst channel = jetsocket.subscribe("private-encrypted-my-channel");
// Server-side (requires encryption master key)const jetsocket = new Jetsocket({ appId: "APP_ID", key: "APP_KEY", secret: "APP_SECRET", cluster: "APP_CLUSTER", encryptionMasterKey: "your-encryption-key"});Webhook Verification
Section titled “Webhook Verification”Webhooks are automatically verified to ensure they come from Jetsocket.io and haven’t been tampered with.
app.post("/jetsocket/webhook", (req, res) => { const webhook = jetsocket.webhook(req);
if (webhook.isValid()) { // Process webhook events res.status(200).send("OK"); } else { res.status(400).send("Invalid webhook"); }});Best Practices
Section titled “Best Practices”Always Authenticate Users
Section titled “Always Authenticate Users”// Good: Always verify user identityapp.post("/jetsocket/auth", authenticateUser, (req, res) => { const user = req.user; const channel = req.body.channel_name;
if (canAccessChannel(user, channel)) { const authResponse = jetsocket.authorizeChannel(req.body.socket_id, channel); res.send(authResponse); } else { res.status(403).send("Forbidden"); }});
// Bad: No authenticationapp.post("/jetsocket/auth", (req, res) => { const authResponse = jetsocket.authorizeChannel(req.body.socket_id, req.body.channel_name); res.send(authResponse);});Validate Channel Names
Section titled “Validate Channel Names”function canAccessChannel(user, channel) { // Validate channel name format if (!channel || typeof channel !== 'string') { return false; }
// Check for private channel prefix if (channel.startsWith('private-')) { // Extract user ID from channel name const userId = channel.replace('private-user-', ''); return user.id === userId; }
return false;}Use HTTPS
Section titled “Use HTTPS”Always use HTTPS for your authorization endpoints:
// Good: HTTPS endpointconst jetsocket = new Jetsocket("APP_KEY", { cluster: "APP_CLUSTER", channelAuthorization: { endpoint: "https://yourdomain.com/jetsocket/auth" }});
// Bad: HTTP endpoint (insecure)const jetsocket = new Jetsocket("APP_KEY", { cluster: "APP_CLUSTER", channelAuthorization: { endpoint: "http://yourdomain.com/jetsocket/auth" }});Implement Rate Limiting
Section titled “Implement Rate Limiting”const rateLimit = require("express-rate-limit");
const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100 // limit each IP to 100 requests per windowMs});
app.post("/jetsocket/auth", authLimiter, authenticateUser, (req, res) => { // Authorization logic});Log Authentication Attempts
Section titled “Log Authentication Attempts”app.post("/jetsocket/auth", authenticateUser, (req, res) => { const user = req.user; const channel = req.body.channel_name; const socketId = req.body.socket_id;
console.log(`Auth attempt: User ${user.id} requesting access to ${channel}`);
if (canAccessChannel(user, channel)) { console.log(`Auth success: User ${user.id} granted access to ${channel}`); const authResponse = jetsocket.authorizeChannel(socketId, channel); res.send(authResponse); } else { console.log(`Auth failed: User ${user.id} denied access to ${channel}`); res.status(403).send("Forbidden"); }});Common Patterns
Section titled “Common Patterns”User-Specific Channels
Section titled “User-Specific Channels”// Create a channel for each userconst userId = getCurrentUserId();const channel = jetsocket.subscribe(`private-user-${userId}`);
// Server-side authorizationfunction canAccessChannel(user, channel) { if (channel.startsWith('private-user-')) { const channelUserId = channel.replace('private-user-', ''); return user.id === channelUserId; } return false;}Role-Based Access
Section titled “Role-Based Access”function canAccessChannel(user, channel) { if (channel === 'private-admin-dashboard') { return user.role === 'admin'; }
if (channel === 'private-moderator-chat') { return user.role === 'admin' || user.role === 'moderator'; }
return false;}Group-Based Access
Section titled “Group-Based Access”function canAccessChannel(user, channel) { if (channel.startsWith('private-group-')) { const groupId = channel.replace('private-group-', ''); return user.groups.includes(groupId); } return false;}Error Handling
Section titled “Error Handling”Client-Side Error Handling
Section titled “Client-Side Error Handling”const channel = jetsocket.subscribe("private-my-channel");
channel.bind("jetsocket:subscription_error", (error) => { console.error("Authorization failed:", error);
if (error.status === 403) { // Handle access denied showMessage("You don't have permission to access this channel"); } else if (error.status === 401) { // Handle authentication required redirectToLogin(); } else { // Handle other errors showMessage("Failed to connect to channel"); }});Server-Side Error Handling
Section titled “Server-Side Error Handling”app.post("/jetsocket/auth", async (req, res) => { try { const user = await authenticateUser(req); const channel = req.body.channel_name;
if (canAccessChannel(user, channel)) { const authResponse = jetsocket.authorizeChannel(req.body.socket_id, channel); res.send(authResponse); } else { res.status(403).send("Forbidden"); } } catch (error) { console.error("Auth error:", error); res.status(500).send("Internal server error"); }});Next Steps
Section titled “Next Steps”- Learn about channel authorization in detail
- Explore user authentication for user management
- Check out encrypted channels for additional security
- See security best practices for comprehensive guidance