Identity validation
When you call setUser from the browser, anyone who reads your JavaScript can claim to be any of your customers. Identity validation closes that hole by requiring a signature only your server can produce.
How it works
Each web widget inbox carries a private secret — the HMAC token — that lives only on the server side. To prove a visitor really is the user you say they are, you sign their identifier with that token using HMAC-SHA256 and pass the result alongside the user data.
- Your backend reads the HMAC token from the dashboard once and stores it as a secret.
- When you render a page for a logged-in user, your backend computes
identifier_hash = HMAC-SHA256(identifier, hmacToken). - The hash is injected into the page and passed to
$hellouOne.setUser. - HellouOne re-computes the hash on its end and only accepts the identity if it matches.
The signature covers the identifier string and nothing else. Name, email, avatar URL and other user fields travel alongside it but are not part of the hash — treat the identifier as the canonical “who is this” field.
1. Find your HMAC token
In the dashboard, open Inboxes → (your web widget) → Configuration. The HMAC token is shown beneath the embed snippet. Copy it into a secret store on your backend — never commit it to a public repo and never expose it to the browser.
2. Compute the hash on the server
Below are minimal examples in a few common languages. In every case, the input is the user’s identifier as a string and the key is the HMAC token.
Node.js
const crypto = require('crypto');
const identifierHash = crypto
.createHmac('sha256', process.env.HELLOUONE_HMAC_TOKEN)
.update(String(user.id))
.digest('hex');
Ruby
require 'openssl'
identifier_hash = OpenSSL::HMAC.hexdigest(
'sha256',
ENV.fetch('HELLOUONE_HMAC_TOKEN'),
user.id.to_s
)
Python
import hmac, hashlib, os
identifier_hash = hmac.new(
os.environ['HELLOUONE_HMAC_TOKEN'].encode(),
str(user.id).encode(),
hashlib.sha256
).hexdigest()
PHP
$identifierHash = hash_hmac(
'sha256',
(string) $user->id,
getenv('HELLOUONE_HMAC_TOKEN')
);
3. Pass the hash to the browser
Render the hash into the page along with the rest of the user payload, then hand it to $hellouOne.setUser after the SDK is ready.
<script>
window.addEventListener('hellouone:ready', function () {
window.$hellouOne.setUser('42', {
name: 'Ada Lovelace',
email: '[email protected]',
avatar_url: 'https://example.com/ada.png',
phone_number: '+15551234567',
identifier_hash: '<%= identifier_hash %>'
});
});
</script>
The hash on the server must be computed against the string form of the identifier. If you sign 42 as an integer in one place and pass "42" as a string elsewhere, the digests will not match and the call will be rejected.
Mandatory vs. optional mode
Each web widget can be configured in one of two modes:
- Optional —
setUserworks with or withoutidentifier_hash. When the hash is present and matches, the resulting contact is marked verified. - Mandatory —
setUseris rejected unlessidentifier_hashis present and matches. Use this when you have signed-in users and want to guarantee impersonation isn’t possible from the browser.
Rotating the token
If the HMAC token leaks (e.g. it ended up in a client bundle by mistake), rotate it from the dashboard. Every previously-issued hash becomes invalid immediately, so re-deploy your backend with the new secret as part of the same change — otherwise live sessions will start failing.