Besucher identifizieren und Kontext übergeben
Wie du angemeldete Nutzer mit ReactiveChat('identify') meldest, den userHash per HMAC-SHA256 auf deinem Server signierst, das Geheimnis rotierst und dem Assistenten strukturierten Seitenkontext wie Produkt oder Warenkorb mitgibst.
Weiß deine Website, wer gerade da ist, sag es dem Chat. Dann sieht dein Team im Pult einen Namen statt „Besucher 4f2a“, und Funktionen wie Kundendaten und das Kundenportal werden überhaupt erst möglich.
Der Grundsatz dabei: Der Browser beweist nichts. Was eine Seite über identify behauptet, kann jeder Besucher in der Konsole fälschen. Als bestätigt gilt ein Nutzer nur mit einer Signatur, die dein Server mit einem Geheimnis berechnet hat, das den Browser nie erreicht.
Der Aufruf im Browser
ReactiveChat('identify', {
userId: '4711',
email: 'kim@example.com',
name: 'Kim Berger',
userHash: '9c1f…',
exp: 1792503600
});
- userId (String, empfohlen) – deine eigene, dauerhafte Kennung des Nutzers. Keine E-Mail-Adresse, keine fortlaufende Nummer, die sich ändern kann.
- email (String, optional) – wird im Pult angezeigt. Bestätigt ist sie nur, wenn sie mitsigniert wurde (unten).
- name (String, optional) – Anzeigename im Pult.
- userHash (String, für die Bestätigung Pflicht) – 64 Hex-Zeichen, auf deinem Server berechnet.
- exp (Ganzzahl, empfohlen) – Ablaufzeit des Hashes in Unix-Sekunden, höchstens 24 Stunden in der Zukunft.
Andere Felder werden verworfen. identify darf vor dem Laden des Widgets stehen; es landet in der Warteschlange und löst kein vorzeitiges Laden aus. Die Werte reisen beim Verbindungsaufbau mit und, wenn das Widget schon verbunden ist, sofort.
Das Geheimnis
Im Konto unter Projekt → Identitätsprüfung erzeugst du das Geheimnis des Projekts (Recht: Projekt bearbeiten). Es besteht aus 64 Hex-Zeichen und wird genau einmal vollständig angezeigt, danach nur noch als Maske. Lege es in die Umgebung deines Servers – nie in ein Skript im Browser, in eine App oder in ein Repository.
Wichtig für die Berechnung: Schlüssel des HMAC ist die 64-stellige Zeichenkette selbst, so wie sie angezeigt wird – nicht die daraus dekodierten Bytes.
Die Signatur berechnen
userHash = hex( HMAC_SHA256( geheimnis, userId + "." + exp ) )
Kleinbuchstaben-Hex, 64 Zeichen. Mit bestätigter E-Mail-Adresse:
userHash = hex( HMAC_SHA256( geheimnis, userId + "." + exp + "." + email ) )
Nur in der zweiten Form gilt die E-Mail-Adresse als bestätigt. Sie setzt exp voraus.
PHP:
<?php
$geheim = getenv('RC_IDENT_SECRET'); // 64 Hex-Zeichen aus dem Konto
$userId = (string) $kunde->id;
$exp = time() + 3600; // hoechstens 24 h
$userHash = hash_hmac('sha256', $userId . '.' . $exp, $geheim);
?>
<script nonce="<?= $cspNonce ?>">
ReactiveChat('identify', {
userId: <?= json_encode($userId) ?>,
userHash: <?= json_encode($userHash) ?>,
exp: <?= (int) $exp ?>
});
</script>
Node.js:
const crypto = require('crypto');
function rcIdentitaet(kunde) {
const userId = String(kunde.id);
const exp = Math.floor(Date.now() / 1000) + 3600;
const userHash = crypto.createHmac('sha256', process.env.RC_IDENT_SECRET)
.update(userId + '.' + exp)
.digest('hex');
return { userId, userHash, exp };
}
Python:
import hmac, hashlib, os, time
def rc_identitaet(kunde_id: str) -> dict:
exp = int(time.time()) + 3600
msg = f"{kunde_id}.{exp}".encode()
key = os.environ["RC_IDENT_SECRET"].encode() # die Hex-Zeichenkette als Text
return {"userId": kunde_id, "exp": exp,
"userHash": hmac.new(key, msg, hashlib.sha256).hexdigest()}
Mit E-Mail-Adresse (PHP):
$userHash = hash_hmac('sha256', $userId . '.' . $exp . '.' . $email, $geheim);
Die Adresse muss genau so signiert werden, wie du sie an identify übergibst.
Ohne Inline-Skript (strenge CSP)
Erlaubt deine Content-Security-Policy keine Inline-Skripte, gib die Werte als Daten aus und rufe identify aus einer eigenen Skriptdatei auf:
<meta name="rc-ident" content='{"userId":"4711","userHash":"9c1f…","exp":1792503600}'>
// /js/chat-ident.js
var m = document.querySelector('meta[name="rc-ident"]');
if (m) { ReactiveChat('identify', JSON.parse(m.content)); }
In Single-Page-Apps holst du die drei Werte nach der Anmeldung per fetch von deinem Server.
Was der Server prüft
expist eine ganze Zahl (Unix-Sekunden), liegt in der Zukunft und höchstens 24 Stunden (plus 5 Minuten Toleranz) voraus.- Der Hash passt zu
userId + "." + exp(oder mit E-Mail). Großbuchstaben im Hash werden toleriert. - Verglichen wird zeitkonstant.
Bestätigt und frisch ist ein Nutzer mit gültigem Hash und exp. Nur so bekommt er Kundendaten und das Kundenportal.
Ältere Form ohne exp: userHash = HMAC_SHA256(geheimnis, userId) wird weiterhin als bestätigt angenommen, aber nicht als frisch – für Gesprächsverlauf und Anzeige im Pult genügt sie, für Kundendaten nicht. Stelle bestehende Einbauten auf die Form mit exp um.
Wenn die Prüfung scheitert
Der Chat funktioniert weiter, aber anonym. Das Widget bekommt den Fehler auth_failed mit einem Grund in detail.reason:
- no_hash –
userHashfehlt. - no_secret – für das Projekt ist kein Geheimnis eingerichtet.
- bad_exp –
expist keine gültige Ganzzahl in Sekunden (oft: Millisekunden übergeben). - expired –
expliegt in der Vergangenheit (Seite lange offen, Serveruhr falsch). - exp_too_far –
expliegt mehr als 24 Stunden voraus. - bad_hash – der Hash passt nicht: falsches Geheimnis, falsche Reihenfolge,
userIdals Zahl statt Zeichenkette signiert, E-Mail anders geschrieben.
Im Netzwerk-Reiter der Entwicklerwerkzeuge steht der Grund im Rahmen error der WebSocket-Verbindung; init_ok.identity zeigt verified und reason.
Eine Einstellung „nur bestätigte Besucher zulassen“ gibt es nicht: Unbestätigte Besucher chatten immer als anonyme Besucher.
Das Geheimnis rotieren
- Neues Geheimnis erzeugen: Das bisherige gilt noch 24 Stunden weiter. Trag das neue in dieser Zeit auf deinen Servern ein.
- Entfernen: macht beide sofort ungültig. Alle Nutzer gelten dann bis zum Einrichten eines neuen Geheimnisses als unbestätigt.
Nutzerwechsel und Abmelden
- Rufst du
identifymit einem anderen Nutzer auf (etwa nach einem Kontowechsel in einer SPA), trennt das Widget den Eingabe-Entwurf vom vorigen Nutzer. - Einen eigenen Befehl zum Abmelden gibt es nicht. Die Identität gilt nur für den laufenden Seitenaufruf: Liefere nach dem Abmelden Seiten ohne
identifyaus. Gespräch und Besucherkennung bleiben im Browser erhalten; soll ein gemeinsam genutztes Gerät nichts mehr zeigen, kann der Besucher im Widget seine Daten löschen.
Kontext übergeben
Neben der Identität kann deine Seite dem Assistenten und deinem Team sagen, worum es gerade geht – etwa welches Produkt angezeigt wird oder was im Warenkorb liegt. Das geht über track:
ReactiveChat('track', 'warenkorb', {
page_type: 'cart',
cart_value: 129.80,
cart_items: 3,
currency: 'EUR'
});
Übernommen werden nur diese Felder; alles andere wird verworfen:
- Seite:
url,path,title,referrer,page_type,landing_path - Produkt:
product_id,variant_id,category,price,currency,in_stock - Warenkorb:
cart_value,cart_items - Kampagne:
utm_source,utm_medium,utm_campaign,gclid,msclkid,fbclid - Signale:
intent,intent_confidence,rage_score,scroll_pct,dwell_ms
Adresse, Titel, Herkunft und Kampagnenparameter erfasst das Widget bei jedem Seitenwechsel ohnehin selbst. Kontext wird nur mit Einwilligung übertragen (Datenschutz-Einbindung). Schreibe keine personenbezogenen Daten in diese Felder – dafür ist identify da.
Mobile Apps
In einer App übergibst du die Identität nach dem Laden des WebViews per JavaScript, nie über die Adresse. Der Hash wird auch hier auf deinem Server berechnet, nicht in der App: Mobile Apps.
Weiter: Kundendaten-Endpunkt · SPA und Seitenwechsel
Posledná aktualizácia: