JWT Integration
Authenticate users with your existing JWT tokens. No separate login required.
How It Works
You Sign
Your backend signs a JWT with the shared secret when users log in.
Widget Passes
The widget sends the token with API requests to SupportFlow.
We Verify
SupportFlow verifies the token and identifies the user.
Setup
1. Generate a Secret
Generate a secure random string (at least 32 characters):
openssl rand -base64 322. Add to SupportFlow
Go to your app's Settings page in the admin panel and paste the secret.
3. Add to Your Backend
SUPPORT_JWT_SECRET=your-generated-secret-hereToken Structure
Your JWT must include these claims:
{
"sub": "user-123", // Required: User ID
"email": "user@example.com", // Required: User email
"name": "John Doe", // Optional: Display name
"iat": 1704067200, // Issued at timestamp
"exp": 1704153600 // Expiration (recommended: 24h)
}Note: The sub claim should match your internal user ID. This is used to track issues and chat history.
Signing Tokens
Node.js
import jwt from 'jsonwebtoken'
function generateSupportToken(user) {
return jwt.sign(
{
sub: user.id,
email: user.email,
name: user.name,
},
process.env.SUPPORT_JWT_SECRET,
{ expiresIn: '24h' }
)
}
// Usage
const token = generateSupportToken({
id: 'user-123',
email: 'user@example.com',
name: 'John Doe'
})Python
import jwt
import os
from datetime import datetime, timedelta
def generate_support_token(user):
payload = {
'sub': user['id'],
'email': user['email'],
'name': user.get('name'),
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(hours=24)
}
return jwt.encode(
payload,
os.environ['SUPPORT_JWT_SECRET'],
algorithm='HS256'
)
# Usage
token = generate_support_token({
'id': 'user-123',
'email': 'user@example.com',
'name': 'John Doe'
})Go
package main
import (
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
func GenerateSupportToken(user User) (string, error) {
claims := jwt.MapClaims{
"sub": user.ID,
"email": user.Email,
"name": user.Name,
"iat": time.Now().Unix(),
"exp": time.Now().Add(24 * time.Hour).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(os.Getenv("SUPPORT_JWT_SECRET")))
}Security Best Practices
Use HTTPS
Always transmit tokens over HTTPS to prevent interception.
Set expiration
Use short-lived tokens (24 hours recommended) and refresh as needed.
Keep secret secure
Store the secret in environment variables, never in code or version control.
Never expose the secret client-side
JWT signing must happen on your backend. The secret should never be in frontend code.
Testing Your Token
Test your token generation by decoding it at jwt.io (use only test data, never production tokens).
Or verify programmatically:
curl -X POST "https://support.example.com/api/support/myapp/chat" \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}'
# A 200 response means authentication succeeded
# A 401 response means the token is invalid