Authentication
Identify authenticated user with JWT
By default, the Ticketping widget can be embedded without authentication.
If you want to associate chats with logged-in users from your product, you’ll need to issue a JWT token for each user session.
Steps
1. Generate a JWT Secret
- Go to Ticketping dashboard API Keys.
- Click New API Key.
- This will generate a pair of API key and JWT Secret.
- Copy JWT Secret and keep it safe. This secret is used to sign all JWTs issued by your server.
Never expose this secret in your frontend code. It should only be stored on your backend.
2. Create an API in your backend codebase
You’ll need an endpoint that your frontend chat widget can call to fetch a signed JWT for the current user.
The JWT must include some user identifiers and have a short expiration (we recommend 5 minutes).
Field | Required | Description |
---|---|---|
external_id | ✅ | Unique user ID in your system |
email | ✅ | User’s email address |
display_name | Optional | Friendly name to show in Ticketping |
exp | ✅ | Expiration timestamp (short-lived recommended) |
import express from "express";
import jwt from "jsonwebtoken";
const app = express();
// Protect this route with your own authentication middleware
app.get("/api/ticketping/chat-jwt", (req, res) => {
const user = req.user; // Assume you set this via auth middleware
const payload = {
external_id: user.id,
email: user.email,
display_name: user.name || user.email.split("@")[0],
exp: Math.floor(Date.now() / 1000) + 60 * 5, // expires in 5 min
};
const token = jwt.sign(payload, process.env.TICKETPING_JWT_SECRET);
res.json({ jwt: token });
});
3. Pass the JWT to the widget
On your frontend, call your new API and provide the token when initializing the widget via userJWT
param:
window.TicketpingChat.init({
appId: 'your-app-id',
teamSlug: 'your-team-slug',
teamLogoIcon: 'cdn-link-to-your-logo-square',
userJWT: 'jwt-encoded-string-returned-by-your-API'
});
Examples in specific frameworks
import React, { useEffect, useRef, useState } from 'react';
import TicketpingChat from '@ticketping/chat-widget/react';
const myTheme = {
primaryColor: '#007BFF',
primaryHover: '#0056b3',
textPrimary: '#111827',
textSecondary: '#374151',
textMuted: '#6b7280',
background: '#ffffff',
backgroundSecondary: '#f3f4f6',
backgroundTertiary: '#e5e7eb',
};
// helper function to fetch JWT
async function fetchJwt() {
try {
const res = await fetch('/api/ticketping/chat-jwt', { credentials: 'include' });
if (res.ok) {
const { jwt } = await res.json();
return jwt || '';
}
} catch (err) {
console.error('Failed to fetch JWT:', err);
}
return '';
}
function App() {
const chatRef = useRef();
const [jwtToken, setJwtToken] = useState(null);
const [jwtLoaded, setJwtLoaded] = useState(false);
useEffect(() => {
fetchJwt().then(token => {
setJwtToken(token);
setJwtLoaded(true);
});
}, []);
return (
<div>
<h1>My App</h1>
{jwtLoaded && (
<TicketpingChat
ref={chatRef}
appId="your-app-id"
teamSlug="your-team-slug"
teamLogoIcon="cdn-link-to-your-logo-square"
theme={myTheme}
userJWT={jwtToken}
/>
)}
</div>
);
}
export default App;
Security Notes
- Always sign JWTs on your backend using the secret from the dashboard.
- Keep expiration short. The widget will request a fresh token as needed.
- Do not expose your JWT secret in frontend code or version control.