Identificar visitantes y transmitir contexto
Cómo comunicar usuarios con sesión iniciada mediante ReactiveChat('identify'), firmar userHash con HMAC-SHA256 en su servidor, rotar el secreto y transmitir al asistente contexto estructurado de la página, como el producto o el carrito.
Si su sitio web sabe quién está presente, comuníqueselo al chat. Así, su equipo ve un nombre en el panel de agentes en lugar de «Visitante 4f2a» y se hacen posibles funciones como los datos de clientes y el portal de clientes.
El principio: el navegador no demuestra nada. Cualquier visitante puede falsificar en la consola lo que una página declare mediante identify. Un usuario solo se considera confirmado con una firma calculada por su servidor con un secreto que nunca llega al navegador.
La llamada en el navegador
ReactiveChat('identify', {
userId: '4711',
email: 'kim@example.com',
name: 'Kim Berger',
userHash: '9c1f…',
exp: 1792503600
});
- userId (cadena, recomendado) – su ID permanente del usuario. No una dirección de correo ni un número secuencial que pueda cambiar.
- email (cadena, opcional) – se muestra en el panel de agentes. Solo se confirma si también se ha firmado (más abajo).
- name (cadena, opcional) – nombre visible en el panel de agentes.
- userHash (cadena, obligatorio para confirmar) – 64 caracteres hexadecimales, calculados en su servidor.
- exp (entero, recomendado) – caducidad del hash en segundos Unix, como máximo 24 horas en el futuro.
Los demás campos se descartan. identify puede llegar antes de que se haya cargado el widget; se pone en cola y no provoca una carga anticipada. Los valores se transmiten al establecer la conexión y, si el widget ya está conectado, de inmediato.
El secreto
En Proyecto → Verificación de identidad de su cuenta puede generar el secreto del proyecto (permiso: editar el proyecto). Consta de 64 caracteres hexadecimales y se muestra completo exactamente una vez; después, solo oculto. Guárdelo en el entorno de su servidor, nunca en un script del navegador, en una aplicación o en un repositorio.
Importante para el cálculo: la clave HMAC es la propia cadena de 64 caracteres, exactamente como se muestra, no los bytes descodificados a partir de ella.
Calcular la firma
userHash = hex( HMAC_SHA256( secret, userId + "." + exp ) )
Hexadecimal en minúsculas, 64 caracteres. Con una dirección de correo confirmada:
userHash = hex( HMAC_SHA256( secret, userId + "." + exp + "." + email ) )
Solo en la segunda forma se considera confirmada la dirección de correo. Requiere exp.
PHP:
<?php
$geheim = getenv('RC_IDENT_SECRET'); // 64 hex characters from the account
$userId = (string) $kunde->id;
$exp = time() + 3600; // at most 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() # the hex string as text
return {"userId": kunde_id, "exp": exp,
"userHash": hmac.new(key, msg, hashlib.sha256).hexdigest()}
Con una dirección de correo (PHP):
$userHash = hash_hmac('sha256', $userId . '.' . $exp . '.' . $email, $geheim);
La dirección debe firmarse exactamente como se transmite a identify.
Sin script en línea (CSP estricta)
Si su política de seguridad de contenido no permite scripts en línea, emita los valores como datos y llame a identify desde un archivo de script propio:
<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)); }
En aplicaciones de una sola página, obtenga los tres valores de su servidor mediante fetch después de iniciar sesión.
Qué comprueba el servidor
expes un entero (segundos Unix), está en el futuro y como máximo 24 horas por delante (más 5 minutos de tolerancia).- El hash coincide con
userId + "." + exp(o la forma con correo). Se toleran las letras mayúsculas en el hash. - La comparación se realiza en tiempo constante.
Un usuario está confirmado y con verificación vigente si tiene un hash válido y exp. Solo entonces obtiene datos de clientes y acceso al portal de clientes.
Forma antigua sin exp: userHash = HMAC_SHA256(secret, userId) sigue aceptándose como confirmada, pero no como vigente: basta para el historial de conversación y la visualización en el panel de agentes, no para datos de clientes. Cambie las integraciones existentes a la forma con exp.
Cuando falla la comprobación
El chat sigue funcionando, pero de forma anónima. El widget recibe el error auth_failed con un motivo en detail.reason:
- no_hash – falta
userHash. - no_secret – no se ha configurado un secreto para el proyecto.
- bad_exp –
expno es un entero válido en segundos (a menudo se han transmitido milisegundos). - expired –
expestá en el pasado (página abierta durante mucho tiempo, reloj del servidor incorrecto). - exp_too_far –
expestá más de 24 horas en el futuro. - bad_hash – el hash no coincide: secreto incorrecto, orden incorrecto,
userIdfirmado como número en lugar de cadena o correo escrito de otra forma.
En la pestaña de red de las herramientas de desarrollo, el motivo está en la trama error de la conexión WebSocket; init_ok.identity muestra verified y reason.
No hay un ajuste para permitir solo visitantes confirmados: los no confirmados siempre chatean como visitantes anónimos.
Rotar el secreto
- Generar nuevo secreto: el anterior sigue siendo válido durante otras 24 horas. Introduzca el nuevo en sus servidores dentro de ese plazo.
- Eliminar: invalida ambos de inmediato. Todos los usuarios se consideran entonces no confirmados hasta que se configure un secreto nuevo.
Cambiar de usuario y cerrar sesión
- Si llama a
identifycon un usuario distinto (por ejemplo, tras cambiar de cuenta en una SPA), el widget separa el borrador de entrada del usuario anterior. - No hay un comando específico para cerrar sesión. La identidad solo se aplica a la visita actual a la página: después de cerrar sesión, sirva páginas sin
identify. El ID de conversación y el de visitante se conservan en el navegador; si en un dispositivo compartido no debe seguir mostrándose nada, el visitante puede eliminar sus datos en el widget.
Transmitir contexto
Además de la identidad, su página puede comunicar al asistente y a su equipo qué está ocurriendo ahora, por ejemplo qué producto se muestra o qué hay en el carrito. Se realiza mediante track:
ReactiveChat('track', 'warenkorb', {
page_type: 'cart',
cart_value: 129.80,
cart_items: 3,
currency: 'EUR'
});
Solo se incorporan estos campos; todo lo demás se descarta:
- Página:
url,path,title,referrer,page_type,landing_path - Producto:
product_id,variant_id,category,price,currency,in_stock - Carrito:
cart_value,cart_items - Campaña:
utm_source,utm_medium,utm_campaign,gclid,msclkid,fbclid - Señales:
intent,intent_confidence,rage_score,scroll_pct,dwell_ms
El widget ya registra por sí solo la dirección, el título, la página de referencia y los parámetros de campaña en cada cambio de página. El contexto solo se transmite con consentimiento (Integración de privacidad). No escriba datos personales en estos campos; para ello está identify.
Aplicaciones móviles
En una aplicación, transmita la identidad mediante JavaScript después de que se haya cargado la WebView, nunca mediante la dirección. También aquí el hash se calcula en su servidor, no en la aplicación: Aplicaciones móviles.
Siguiente: Endpoint de datos de clientes · SPA y cambios de página
Ìgbà àtúnṣe tó kẹ́yìn: