Deskwerk· Werkstatt

WissenMessaging-Widget

JWT-Login: das Widget weiss, wer schreibt

Ohne Authentifizierung ist jede Widget-Konversation anonym: Das Widget fragt nach dem Namen, der Verlauf klebt am Browser, und das Team weiss nicht, ob «Max» wirklich Max ist. Mit JWT-Login dreht sich das: Die Website sagt dem Widget kryptografisch signiert, wer eingeloggt ist.

Was sich dadurch ändert

  • Keine Datenabfrage mehr: Name und E-Mail sind bekannt, die Konversation startet direkt.
  • Ein Verlauf über Geräte hinweg: Dieselbe Kundin sieht ihre Konversation auf Laptop und Handy. Der Verlauf hängt an der Identität, nicht am Browser.
  • Verlässlicher Kontext: Das Ticket gehört einem echten, identifizierten Kundenprofil. Automatisierung und Agenten arbeiten mit gesicherten Daten statt mit Angaben aus einem Formularfeld.

Die Architektur in einem Bild

Das Widget authentifiziert nie selbst. Es reicht nur ein Token weiter, das dein Backend ausstellt:

Browser (eingeloggt)              Dein Backend                    Zendesk
       │  «gib mir ein Chat-Token»     │                             │
       ├──────────────────────────────►│  signiert JWT               │
       │◄──────────────────────────────┤  (Shared Secret)            │
       │  zE loginUser(jwt) ───────────┼────────────────────────────►│ verifiziert

Im Frontend ist das ein Callback, der das Token holt, und zwar jedes Mal frisch. So werden abgelaufene Tokens automatisch erneuert:

zE('messenger', 'loginUser', async (callback) => {
  const antwort = await fetch('/api/chat-token'); // dein Endpoint, nur für eingeloggte Nutzer
  const { jwt } = await antwort.json();
  callback(jwt);
});

// Beim Abmelden der Website gehört auch der Chat abgemeldet:
zE('messenger', 'logoutUser');

Das Token selbst signiert dein Backend mit einem Signing Key aus dem Admin Center und einer Identität aus deinem System (eine stabile externe ID, dazu Name und E-Mail). Es ist kurzlebig: Läuft exp ab, weist Zendesk den Aufruf zurück, das Widget fragt deinen Callback erneut. Deshalb der dynamische Fetch statt eines fest verdrahteten Tokens.

HEADER alg: HS256 kid: <key-id> signiert mit dem Shared Secret PAYLOAD scope: "user" external_id: "u_8213" ← stabile ID (Regel 4) name · email exp: 1739… ← kurze Laufzeit
Das signierte Token, decodiert: der Header nennt Algorithmus und Key-ID, die Payload trägt die Identität — vor allem die stabile external_id und ein kurzes exp.
📸 Screenshot noch einzufügen Admin Center → Security → End user authentication → Messaging: der Signing-Key-Dialog («Copy shared secret»). public/werkstatt/bauplaene/jwt-login/admin-signing-key-erstellen.png
Der Signing Key entsteht einmalig im Admin Center — danach ist er nicht mehr sichtbar, also gleich sicher ablegen.

Die Sicherheitsregeln

  1. Der Signing Key bleibt auf dem Server. Ein Secret im Frontend-Code ist ein öffentliches Secret. Dann kann sich jeder als jede ausgeben.
  2. Der Token-Endpoint prüft die Session. Nur wer bei dir eingeloggt ist, bekommt ein Token. Der Endpoint ist Teil deiner Auth, nicht davor.
  3. Kurze Laufzeiten statt statischer Tokens. Zendesk selbst rät von statischen Tokens ab; der Refresh über den Callback ist der vorgesehene Weg.
  4. Identität konsistent halten: Dieselbe externe ID wie in deinem Kundensystem. Sonst entstehen Duplikat-Profile statt einer sauberen Historie.

Ein Login, die ganze Support-Oberfläche

Der eigentliche Gewinn zeigt sich, wenn dieselbe Identität nicht nur das Widget trägt, sondern die ganze Support-Oberfläche. Das Help Center hat einen eigenen JWT-Weg: Single Sign-on mit eigenem Secret, ein signiertes Token an den Zendesk-SSO-Endpunkt. Technisch getrennt vom Messaging-Token oben, aber gespeist aus derselben Quelle: dem Login in deinem eigenen System.

Zwei Türen, ein Schlüssel. Wer sich einmal bei dir anmeldet, ist zugleich im Widget bekannt und im Help Center eingeloggt, ohne zweiten Login und ohne zweites Passwort. Für die Kundschaft verschwindet die Grenze zwischen Wissensdatenbank, «meine Anfragen» und Chat; es fühlt sich an wie ein Ort, nicht wie drei Systeme.

Dein System ein Login · eine Identität Messaging-Widget loginUser · Secret A Help Center SSO-Endpunkt · Secret B
Zwei Türen, ein Schlüssel: zwei technisch getrennte JWT-Wege mit je eigenem Secret, gespeist aus einer Identität in deinem System.

Das schaltet die interessanten Dinge erst frei: Ein eingeloggtes Help Center kann persönlich werden, etwa eine «Meine Anfragen»-Seite, die den echten Stand der eigenen Tickets zeigt. Das ist ein eigener Bauplan wert.

Warum es hierfür kein Live-Werkstück gibt

Ein echter JWT-Login braucht ein Login-System und ein Backend, das Tokens signiert. Auf einer statischen Demo-Seite wäre alles daran gestellt. Statt einer Attrappe gibt es diesen Bauplan. Wer den Einbau live sehen will: Solche Anbindungen baue ich in Kundenprojekten, inklusive des Token-Endpoints.

← Zurück zu: Messaging-Widget