Skip to content

Private channels

Private channels require authentication before clients can subscribe. This makes them perfect for sending sensitive or user-specific data.

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);
});

You need to set up an authorization endpoint on your server:

// Express.js example
app.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");
}
});

Private channels must start with private-:

// Valid private channel names
jetsocket.subscribe("private-user-123");
jetsocket.subscribe("private-chat-room-456");
jetsocket.subscribe("private-notifications");
jetsocket.subscribe("private-admin-dashboard");

The authorization endpoint receives a POST request with:

  • socket_id: The client’s socket ID
  • channel_name: The channel being subscribed to

Your endpoint should return either:

  • Success: The authorization response from jetsocket.authorizeChannel()
  • Failure: A 403 status code
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 users
const 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);

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);
});

Trigger events on private channels from your server:

jetsocket.trigger("private-user-123", "new-message", {
message: "Hello!",
timestamp: new Date().toISOString()
});

A common pattern is to create channels for individual users:

// Client subscribes to their personal channel
const userId = getCurrentUserId();
const channel = jetsocket.subscribe(`private-user-${userId}`);
channel.bind("notification", (data) => {
showNotification(data.message);
});

Here’s a complete example of a private messaging system:

<!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>
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 endpoint
app.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 endpoint
app.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);

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
  • 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