Dokumentacja

Weryfikacja tożsamości

Rozpoznawaj zalogowaną osobę i przywracaj historię jej rozmów na różnych urządzeniach, używając podpisu kontrolowanego przez Twój backend.

Dlaczego weryfikować#

Domyślnie SDK jest anonimowe: generuje stabilny visitor_id i przechowuje go w magazynie kluczy platformy. To wystarcza dla jednej rozmowy na jednym urządzeniu. Aby rozpoznać konkretnego użytkownika, przywrócić historię po ponownym zalogowaniu lub na innym urządzeniu i niezawodnie powiązać rozmowę z profilem kontaktu, backend potrzebuje dowodu, że klient jest tym, za kogo się podaje. Gdyby SDK po prostu wysłało „jestem użytkownikiem 42”, każdy mógłby podszyć się pod inny identyfikator i odczytać cudzy czat — dlatego Respondo wymaga podpisu kryptograficznego, userHash, który może wygenerować wyłącznie Twój backend.

Uzyskanie identity_secret#

identity_secret to tajny ciąg znaków powiązany z Twoim agentem (pracownikiem AI, z którym połączony jest kanał Twojego widgetu). Wygeneruj go w panelu w sekcji Kanały → Widget → Weryfikacja tożsamości. Sekret żyje na agencie, dlatego jest wspólny dla wszystkich kanałów tego agenta — zarówno widgetu webowego, jak i mobilnego SDK. Nadaje on prawo do podpisywania tożsamości, więc musi żyć wyłącznie na Twoim backendzie i nigdy nie może być dostarczany w aplikacji.

Wzór userHash#

userHash to HMAC-SHA256 z pojedynczego podpisanego ciągu tożsamości, zakodowany jako małe litery hex:

Wzórtext
userHash = HMAC_SHA256( identity_secret, payload )

payload = userId          // jeśli userId jest ustawiony
        = email           // w przeciwnym razie, jeśli email jest ustawiony
        = (invalid)       // jeśli oba są puste, nie ma czego podpisać
  • Sekret to klucz HMAC; ciąg tożsamości to wiadomość — nie odwrotnie.
  • Podpisuj dokładnie jeden ciąg — surowy userId (lub email), bez soli i opakowania JSON.
  • Jeśli przekazujesz zarówno userId, jak i email, podpisz userId (ma priorytet).
  • Wynik to hex (64 znaki dla SHA-256), a nie base64.

Przykłady backendu#

Oblicz podpis na swoim backendzie i przekaż gotowy userHash do aplikacji.

Gogo
import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

// HMAC_SHA256(identity_secret, userId) jako małe litery hex.
func ComputeUserHash(identitySecret, userID string) string {
    mac := hmac.New(sha256.New, []byte(identitySecret))
    mac.Write([]byte(userID))
    return hex.EncodeToString(mac.Sum(nil))
}
Node.jsjavascript
const crypto = require("crypto");

// Zwraca userHash do przekazania do Respondo.identify na kliencie mobilnym.
function computeUserHash(identitySecret, userId) {
  return crypto
    .createHmac("sha256", identitySecret)
    .update(userId, "utf8")
    .digest("hex");
}
Pythonpython
import hmac
import hashlib

# Zwraca userHash do przekazania do Respondo.identify na kliencie mobilnym.
def compute_user_hash(identity_secret: str, user_id: str) -> str:
    return hmac.new(
        identity_secret.encode(),
        user_id.encode(),
        hashlib.sha256,
    ).hexdigest()
PHPphp
<?php
// Zwraca userHash do przekazania do Respondo.identify na kliencie mobilnym.
function computeUserHash(string $identitySecret, string $userId): string {
    return hash_hmac('sha256', $userId, $identitySecret);
}

Jak hash trafia do Respondo#

Respondo nie udostępnia osobnego endpointu tożsamości. Nie ma czego wywoływać: ścieżka /identity nie istnieje i nie trzeba niczego rejestrować. userHash to pole, które jedzie w żądaniach, które SDK i tak wysyła.

Dwa przeskoki, a Ty budujesz tylko pierwszy z nich:

  1. Twój backend → Twoja aplikacja. Hash dostarczasz w dowolny sposób. Najtaniej jest dodać dodatkowe pole do odpowiedzi logowania/bootstrapu, którą i tak zwracasz — bez dodatkowej rundy. Osobny endpoint na Twoim własnym backendzie (na przykład POST /myapp/identity zwracający { userId, userHash }) działa tak samo dobrze. Respondo nie hostuje tego endpointu — implementujesz go Ty.
  2. Twoja aplikacja → Respondo. Tym zajmuje się SDK. Po wywołaniu identify SDK samo dołącza hash do każdego istotnego żądania, a backend weryfikuje go za każdym razem.
Gdzie SDK go umieszcza (informacyjnie — nie wysyłasz tego ręcznie)text
POST /api/v1/chat                      body   identity.userHash
GET  /api/v1/chat/resume               query  user_hash
GET  /api/v1/chat/history              query  user_hash
GET  /api/v1/chat/ws                   frames    user_hash (ramki JSON subscribe/identify po połączeniu — nie w URL handshake'u)
GET  /api/v1/widget/tours              query  user_hash
GET  /api/v1/widget/checklists         query  user_hash
POST /api/v1/widget/push/register      body   user_hash

Hash jest sprawdzany ponownie przy każdym żądaniu, a nie wymieniany raz na sesję — właśnie dlatego skradziony userId sam w sobie jest bezużyteczny.

Jeśli endpoint dostarczający hash na Twoim backendzie nie jest jeszcze zbudowany, żądanie Twojej własnej aplikacji zwróci 404, identify nigdy nie zostanie wywołane, a czat pojedzie anonimowo. To zachowanie oczekiwane, a nie błąd Respondo — 404 na Twojej własnej ścieżce to zadanie po Twojej stronie, a nie zepsuta integracja.

Przekazywanie tożsamości do SDK#

Pobierz podpisaną tożsamość ze swojego backendu, a następnie przekaż userHash do identify na dowolnej platformie:

Kotlinkotlin
Respondo.identify(
    RespondoIdentity(userId = "42", email = "user@example.com", userHash = hash),
)
Swiftswift
Respondo.identify(
    RespondoIdentity(userId: "42", email: "user@example.com", userHash: hash)
)
Dartdart
Respondo.identify(RespondoIdentity(
  userId: '42', email: 'user@example.com', userHash: hash,
));

Zachowanie przy nieprawidłowym userHash#

Gdy weryfikacja jest włączona dla agenta, a podpis jest brakujący lub błędny, backend wykonuje ciche obniżenie do anonimowego: czat nadal działa, visitor_id jest zachowany, a rozmowa jest powiązana z anonimowym kontaktem — ale nie ma powiązania z profilem ani historii między urządzeniami. Jeśli użytkownik „nie jest rozpoznawany”, niemal zawsze chodzi o podpis: sprawdź, czy podpisałeś userId (a nie email czy JSON), czy użyłeś właściwego identity_secret i czy wygenerowałeś małe litery hex. Jeśli identity_secret agenta jest pusty, weryfikacja jest wyłączona, a userId / email są akceptowane bez zmian.

Rotacja identity_secret jest w praktyce twardym przełączeniem: każdy hash wygenerowany starym sekretem natychmiast przestaje przechodzić weryfikację, więc już zalogowani użytkownicy po cichu spadają do anonimowych, dopóki Twój backend nie przeliczy ponownie i nie dostarczy nowego userHash z nowym sekretem. Zmieniaj sekret tylko wtedy, gdy możesz zaktualizować stronę podpisującą w tym samym oknie.