Private channels
Private channels
Section titled “Private channels”Private channels require authentication before clients can subscribe. This makes them perfect for sending sensitive or user-specific data.
Basic usage
Section titled “Basic usage”Client-side subscription
Section titled “Client-side subscription”Private channels are identified by the private- prefix:
const jetsocket = new Jetsocket("APP_KEY", { cluster: "APP_CLUSTER", channelAuthorization: { endpoint: "/jetsocket/auth" }});
const channel = jetsocket.subscribe("private-my-channel");
channel.bind("my-event", (data) => { console.log("Received:", data);});Server-side authorization
Section titled “Server-side authorization”You need to set up an authorization endpoint on your server:
// Express.js exampleapp.post("/jetsocket/auth", (req, res) => { const socketId = req.body.socket_id; const channel = req.body.channel_name;
// Verify the user can access this channel if (canAccessChannel(req.user, channel)) { const authResponse = jetsocket.authorizeChannel(socketId, channel); res.send(authResponse); } else { res.status(403).send("Forbidden"); }});Channel naming
Section titled “Channel naming”Private channels must start with private-:
// Valid private channel namesjetsocket.subscribe("private-user-123");jetsocket.subscribe("private-chat-room-456");jetsocket.subscribe("private-notifications");jetsocket.subscribe("private-admin-dashboard");Authorization endpoint
Section titled “Authorization endpoint”The authorization endpoint receives a POST request with:
socket_id: The client’s socket IDchannel_name: The channel being subscribed to
Your endpoint should return either:
- Success: The authorization response from
jetsocket.authorizeChannel() - Failure: A 403 status code
Complete authorization example
Section titled “Complete authorization example”const express = require("express");const Jetsocket = require("jetsocket");
const app = express();app.use(express.json());
const jetsocket = new Jetsocket({ appId: "APP_ID", key: "APP_KEY", secret: "APP_SECRET", cluster: "APP_CLUSTER",});
// Middleware to authenticate usersconst authenticateUser = (req, res, next) => { // Your authentication logic here const token = req.headers.authorization; if (token) { req.user = verifyToken(token); next(); } else { res.status(401).send("Unauthorized"); }};
app.post("/jetsocket/auth", authenticateUser, (req, res) => { const socketId = req.body.socket_id; const channel = req.body.channel_name; const user = req.user;
// Check if user can access this channel if (canAccessChannel(user, channel)) { const authResponse = jetsocket.authorizeChannel(socketId, channel); res.send(authResponse); } else { res.status(403).send("Forbidden"); }});
function canAccessChannel(user, channel) { // Example logic for channel access control if (channel.startsWith("private-user-")) { const userId = channel.replace("private-user-", ""); return user.id === userId; }
if (channel === "private-admin-dashboard") { return user.role === "admin"; }
return false;}
app.listen(3000);Error handling
Section titled “Error handling”Handle authorization errors on the client:
const channel = jetsocket.subscribe("private-my-channel");
channel.bind("jetsocket:subscription_error", (error) => { console.error("Authorization failed:", error); // Handle the error (show message, redirect, etc.)});
jetsocket.connection.bind("error", (error) => { console.error("Connection error:", error);});Server-side triggering
Section titled “Server-side triggering”Trigger events on private channels from your server:
jetsocket.trigger("private-user-123", "new-message", { message: "Hello!", timestamp: new Date().toISOString()});User-specific channels
Section titled “User-specific channels”A common pattern is to create channels for individual users:
// Client subscribes to their personal channelconst userId = getCurrentUserId();const channel = jetsocket.subscribe(`private-user-${userId}`);
channel.bind("notification", (data) => { showNotification(data.message);});Complete example
Section titled “Complete example”Here’s a complete example of a private messaging system:
Client-side
Section titled “Client-side”<!DOCTYPE html><html><head> <script src="https://js.jetsocket.io/latest/jetsocket.min.js"></script></head><body> <div id="messages"></div> <input type="text" id="messageInput" placeholder="Type a message..."> <button onclick="sendMessage()">Send</button>
<script> const jetsocket = new Jetsocket("APP_KEY", { cluster: "APP_CLUSTER", channelAuthorization: { endpoint: "/jetsocket/auth" } });
const userId = "user-123"; // Get from your auth system const channel = jetsocket.subscribe(`private-user-${userId}`); const messagesDiv = document.getElementById("messages");
channel.bind("new-message", (data) => { const messageElement = document.createElement("div"); messageElement.textContent = `${data.from}: ${data.message}`; messagesDiv.appendChild(messageElement); });
channel.bind("jetsocket:subscription_error", (error) => { console.error("Failed to subscribe:", error); alert("Failed to connect to messaging service"); });
function sendMessage() { const input = document.getElementById("messageInput"); const message = input.value;
if (message.trim()) { fetch("/send-message", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer " + getAuthToken() }, body: JSON.stringify({ message, to: "user-456" }) });
input.value = ""; } } </script></body></html>Server-side
Section titled “Server-side”const express = require("express");const Jetsocket = require("jetsocket");
const app = express();app.use(express.json());
const jetsocket = new Jetsocket({ appId: "APP_ID", key: "APP_KEY", secret: "APP_SECRET", cluster: "APP_CLUSTER",});
// Authorization endpointapp.post("/jetsocket/auth", (req, res) => { const socketId = req.body.socket_id; const channel = req.body.channel_name; const user = getUserFromToken(req.headers.authorization);
if (user && channel === `private-user-${user.id}`) { const authResponse = jetsocket.authorizeChannel(socketId, channel); res.send(authResponse); } else { res.status(403).send("Forbidden"); }});
// Message sending endpointapp.post("/send-message", (req, res) => { const { message, to } = req.body; const from = getUserFromToken(req.headers.authorization);
// Send to recipient's private channel jetsocket.trigger(`private-user-${to}`, "new-message", { from: from.id, message: message, timestamp: new Date().toISOString() });
res.json({ success: true });});
app.listen(3000);Use cases
Section titled “Use cases”Private channels are perfect for:
- Personal notifications: User-specific alerts and updates
- Private messaging: Direct messages between users
- User dashboards: Personal data and settings
- Secure data: Sensitive information that should only be seen by specific users
- Admin features: Administrative functions and controls
Security best practices
Section titled “Security best practices”- Always authenticate users before authorizing channel access
- Validate channel names to prevent unauthorized access
- Use HTTPS for all authorization requests
- Implement rate limiting on your authorization endpoint
- Log authorization attempts for security monitoring
- Use short-lived tokens for authentication
Next steps
Section titled “Next steps”- Learn about presence channels for user tracking
- Explore encrypted channels for additional security
- Check out authentication for more security options