JWT Integration

Authenticate users with your existing JWT tokens. No separate login required.

How It Works

1

You Sign

Your backend signs a JWT with the shared secret when users log in.

2

Widget Passes

The widget sends the token with API requests to SupportFlow.

3

We Verify

SupportFlow verifies the token and identifies the user.

Setup

1. Generate a Secret

Generate a secure random string (at least 32 characters):

Terminalbash
openssl rand -base64 32

2. Add to SupportFlow

Go to your app's Settings page in the admin panel and paste the secret.

3. Add to Your Backend

.envbash
SUPPORT_JWT_SECRET=your-generated-secret-here

Token Structure

Your JWT must include these claims:

JWT Payloadjson
{
  "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

Node.js / TypeScripttypescript
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

Pythonpython
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

Gogo
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:

Test Authenticationbash
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