Appearance
Auth & sessions
The SDK never authenticates the user itself. Your app has already signed the user in; you mint a short-lived session JWT and pass it as sessionToken.
Minting the token (server-side)
Sign a JWT with the same JWT_SECRET the AW Chat backend uses. The only required claim is the user id — as userId (or sub):
ts
import jwt from "jsonwebtoken";
const token = jwt.sign(
{ userId: user.id },
process.env.JWT_SECRET, // must match the backend's JWT_SECRET
{ expiresIn: "1h" }, // keep it short-lived
);Send token to the client and pass it to <AWChat sessionToken={token} />.
Never sign on the client
JWT_SECRET is a server secret. Mint tokens on your backend and deliver them to the app — never embed the secret in client code.
How the backend validates it
Every /api/* request must carry Authorization: Bearer <token>. The backend:
- Verifies the signature against
JWT_SECRET. - Reads
userId(falls back tosub). - Resolves it to an Intercom contact (cached in
user_contacts).
Invalid/expired/missing → 401.
Handling expiry
When the backend returns 401, the SDK calls onSessionExpired and shows a "session expired" panel. Refresh the token and re-mount (or update the sessionToken prop):
tsx
<AWChat
sessionToken={token}
onSessionExpired={async () => {
const fresh = await refreshSupportToken();
setToken(fresh);
}}
/* … */
/>Token contents
- Required:
userIdorsub. - Recommended:
exp(short TTL, e.g. 1h). - Audience/issuer claims are not validated today; keep the secret strong and the TTL short.