Backend token widget authentication
Backend token authentication ties the widget session to your existing auth system. Your backend HMAC-signs a token per user with the Notifizz Node SDK, and the frontend passes it (withuserId and userEmail) to the widget. Notifizz recomputes the HMAC server-side and accepts the session only if they match.
TL;DR
- Server-side:
const token = client.generateHashedToken(userId)— SHA-256 ofuserId + authSecretKey. - Client-side: widget options include
authType: 'backendToken',token,userId,userEmail. - Identity proof: Notifizz recomputes the hash with its own
authSecretKeyand compares — no external IDP roundtrip. - Recommended for production when you have your own auth and don’t already use Firebase.
How it works
Backend mints the token
Call
client.generateHashedToken(userId) from the Notifizz Node SDK. It returns the hex-encoded SHA-256 of userId + authSecretKey.Token shipped to frontend
Return the token alongside the login response or expose a dedicated
/me/notifizz-token endpoint.Backend setup
generateHashedToken() is deterministic — the same userId always produces the same token until you rotate authSecretKey. It does not perform a network call.
The Java and PHP SDKs expose the same helper:
Frontend setup
- React
- Angular
- Vanilla JS
Required fields
| Field | Type | Description |
|---|---|---|
authType | 'backendToken' | Mandatory literal. |
token | string | The output of client.generateHashedToken(userId). |
userId | string | Must match the userId you passed to generateHashedToken. |
userEmail | string | The user’s email address. |
Security
The token is bound to theuserId it was minted for — an intercepted token only unlocks that user’s inbox, not anyone else’s. Rotate authSecretKey (in the dashboard) when you suspect compromise; all previously minted tokens become invalid and your backend will mint new ones on the next session.
FAQ
Where in the dashboard do I find `authSecretKey`?
Where in the dashboard do I find `authSecretKey`?
Environment settings → API keys. There are two server-side keys:
authSecretKey (for generateHashedToken) and sdkSecretKey (for track()). Don’t confuse them — using the wrong one yields a 401 when the widget tries to authenticate.Same `userId`, same token — is that a problem?
Same `userId`, same token — is that a problem?
No. The token is deterministic by design — it’s a function of
userId + authSecretKey. Anyone who has the token can act as that user, but cannot derive a token for another user. Rotate authSecretKey to invalidate existing tokens.How do I rotate `authSecretKey` without downtime?
How do I rotate `authSecretKey` without downtime?
Notifizz accepts a short overlap window where both the old and the new key are valid (configurable in the dashboard). Mint with the old key, deploy your backend to mint with the new key, wait the overlap window, retire the old key. Existing widget sessions stay alive.
The widget shows `hasError: true` after login.
The widget shows `hasError: true` after login.
Most likely the
userId you passed to the widget doesn’t match the userId you passed to generateHashedToken. Double-check both — even a string-vs-number mismatch breaks the hash. Inspect state.errorCode for a typed signal.Can I generate the token from a serverless function?
Can I generate the token from a serverless function?
Yes —
generateHashedToken is a pure SHA-256 computation, no network call. It runs fine in any serverless runtime that has the Notifizz Node SDK installed (or you can implement the same hash manually — see the SDK source).Can I cache the token on the frontend?
Can I cache the token on the frontend?
Yes — the token is stable for as long as
authSecretKey doesn’t rotate. Many apps cache it in a session cookie or localStorage and re-mint only on rotation. Don’t share it across origins.See also
Authentication overview
The four-mode model and when to pick each.
Node.js SDK reference
Full reference for
generateHashedToken() and the rest of the API.Firebase auth
Skip the backend work if you use Firebase Auth.
Publicly-signed JWT
Decouple widget auth from your backend with a managed IDP.