Docs

Vérification d’identité

Reconnaissez une personne connectée et restaurez son historique de conversation sur tous ses appareils, à l’aide d’une signature contrôlée par votre backend.

Pourquoi vérifier#

Par défaut, le SDK est anonyme : il génère un visitor_id stable et le conserve dans le keystore de la plateforme. C’est suffisant pour une conversation sur un appareil. Pour reconnaître un utilisateur précis, restaurer l’historique lors d’une reconnexion ou sur un autre appareil, et lier de façon fiable une conversation à un profil de contact, le backend a besoin d’une preuve que le client est bien celui qu’il prétend être. Si le SDK envoyait simplement « je suis l’utilisateur 42 », n’importe qui pourrait usurper un autre identifiant et lire le chat de quelqu’un d’autre — c’est pourquoi Respondo exige une signature cryptographique, userHash, que seul votre backend peut produire.

Obtenir l’identity secret#

L’identity_secret est une chaîne secrète liée à votre agent (le travailleur IA auquel le canal de votre widget est connecté). Générez-le dans le tableau de bord, sous Canaux → Widget → Vérification d’identité. Comme il réside sur l’agent, tous les canaux rattachés à cet agent — widget web comme SDK mobile — partagent le même secret. Il accorde le droit de signer des identités ; il doit donc résider uniquement sur votre backend et ne doit jamais être livré dans l’application.

La formule du userHash#

userHash est un HMAC-SHA256 sur une unique chaîne d’identité signée, encodé en hexadécimal minuscule :

Formuletext
userHash = HMAC_SHA256( identity_secret, payload )

payload = userId          // si userId est défini
        = email           // sinon, si email est défini
        = (invalide)      // si les deux sont vides, il n'y a rien à signer
  • Le secret est la clé HMAC ; la chaîne d’identité est le message — pas l’inverse.
  • Signez exactement une chaîne — le userId brut (ou l’e-mail), sans sel ni enveloppe JSON.
  • Si vous passez à la fois userId et e-mail, signez le userId (il est prioritaire).
  • La sortie est en hexadécimal (64 caractères pour SHA-256), pas en base64.

Exemples backend#

Calculez la signature sur votre backend et transmettez le userHash finalisé à l’application.

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

// HMAC_SHA256(identity_secret, userId) en hexadécimal minuscule.
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");

// Renvoie le userHash à passer à Respondo.identify sur le client mobile.
function computeUserHash(identitySecret, userId) {
  return crypto
    .createHmac("sha256", identitySecret)
    .update(userId, "utf8")
    .digest("hex");
}
Pythonpython
import hmac
import hashlib

# Renvoie le userHash à passer à Respondo.identify sur le client mobile.
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
// Renvoie le userHash à passer à Respondo.identify sur le client mobile.
function computeUserHash(string $identitySecret, string $userId): string {
    return hash_hmac('sha256', $userId, $identitySecret);
}

Comment le hash parvient à Respondo#

Respondo n’expose aucun endpoint d’identité. Il n’y a aucune route /identity à appeler et rien à enregistrer. userHash est un champ qui voyage dans les requêtes que le SDK effectue déjà.

Deux sauts, et seul le premier est à votre charge :

  1. Votre backend → votre application. Vous livrez le hash comme bon vous semble. L’option la moins coûteuse est un champ supplémentaire dans la réponse de connexion/bootstrap que vous renvoyez déjà — aucun aller-retour additionnel. Un endpoint dédié sur votre propre backend (par exemple POST /myapp/identity renvoyant { userId, userHash }) fonctionne tout aussi bien. Respondo n’héberge pas cet endpoint — c’est vous qui l’implémentez.
  2. Votre application → Respondo. Pris en charge pour vous. Dès que vous appelez identify, le SDK joint le hash à chaque requête concernée et le backend le revérifie à chaque fois.
Où le SDK le place (à titre indicatif — vous n’envoyez pas ces valeurs à la main)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 (subscribe/identify JSON frames after connect — not in the handshake URL)
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

Le hash est revérifié à chaque requête, il n’est pas échangé une seule fois contre une session — c’est ce qui rend un userId volé inutile à lui seul.

Si l’endpoint de livraison sur votre backend n’est pas encore construit, la requête de votre propre application renvoie un 404, identify n’est jamais appelé, et le chat fonctionne en anonyme. C’est le comportement attendu, pas une erreur Respondo — un 404 sur votre propre chemin est une tâche à faire de votre côté, pas une intégration cassée.

Transmettre l’identité au SDK#

Récupérez l’identité signée depuis votre backend, puis passez le userHash à identify sur n’importe quelle plateforme :

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,
));

Comportement en cas de userHash invalide#

Lorsque la vérification est activée sur l’agent et que la signature est manquante ou incorrecte, le backend effectue une rétrogradation silencieuse vers l’anonymat : le chat fonctionne toujours, le visitor_id est conservé, et la conversation est liée au contact anonyme — mais il n’y a aucun lien vers le profil ni d’historique inter-appareils. Si un utilisateur « n’est pas reconnu », c’est presque toujours la signature : vérifiez que vous avez signé le userId (pas l’e-mail ni du JSON), utilisé le bon identity_secret et produit de l’hexadécimal minuscule. Si l’ identity_secret de l’agent est vide, la vérification est désactivée et userId / e-mail sont acceptés tels quels.

Faire tourner l’ identity_secret revient de fait à une bascule brutale : chaque hash produit avec l’ancien secret cesse aussitôt d’être vérifié, si bien que les utilisateurs déjà connectés retombent silencieusement en anonyme jusqu’à ce que votre backend recalcule et refournisse leur userHash avec le nouveau secret. Ne faites tourner le secret que lorsque vous pouvez mettre à jour la partie signature dans la même fenêtre.