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:
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, podpiszuserId(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.
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))
}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");
}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()<?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#
/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:
- 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/identityzwracający{ userId, userHash }) działa tak samo dobrze. Respondo nie hostuje tego endpointu — implementujesz go Ty. - Twoja aplikacja → Respondo. Tym zajmuje się SDK. Po wywołaniu
identifySDK samo dołącza hash do każdego istotnego żądania, a backend weryfikuje go za każdym razem.
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_hashHash 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.
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:
Respondo.identify(
RespondoIdentity(userId = "42", email = "user@example.com", userHash = hash),
)Respondo.identify(
RespondoIdentity(userId: "42", email: "user@example.com", userHash: hash)
)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.