User authentication
Make the widget honor your app's auth boundary using signed JWT tokens.
- Last reviewed
User authentication
If your app already authenticates users, you can make the widget honor the same trust boundary. When enabled, the widget only works for users who have a valid signed token from your app.
How it works
- Enable App Security in your getuserfeedback.com settings.
- Configure your issuer and JWKS endpoint.
- Pass a valid JWT token to the widget from your app.
Once enabled, the widget requires a valid bearer token before it will load
surveys. Tokens are verified per app, and the expected audience is
https://api.getuserfeedback.com.
When security is disabled (the default), the widget works without a token. If you do send one, it's still validated and failures are logged for debugging — so you can test your setup before enforcing it.
Passing the token
Fetch a JWT from your auth provider and pass it to the widget. The token needs to be refreshed periodically — most teams do this on a timer.
React SDK with Clerk
import { useEffect } from "react";import { useAuth } from "@clerk/clerk-react";import { useGetUserFeedback } from "@getuserfeedback/react";const AUTH_REFRESH_INTERVAL_MS = 5 * 60 * 1000;export function GetUserFeedbackAuth() {const client = useGetUserFeedback();const { isLoaded, userId, sessionId, getToken } = useAuth();useEffect(() => {if (!isLoaded) return;let disposed = false;const sync = async () => {if (!userId) {await client.configure({ auth: { jwt: null } });return;}const token = await getToken({ template: "getuserfeedback" });if (disposed) return;await client.configure({auth: { jwt: token ? { token } : null },});};sync();const timer = setInterval(sync, AUTH_REFRESH_INTERVAL_MS);return () => { disposed = true; clearInterval(timer); };}, [client, getToken, isLoaded, sessionId, userId]);return null;}Mount this component once inside both <ClerkProvider> and
<GetUserFeedbackProvider>.
JavaScript SDK
The same pattern works with any auth provider — fetch the token, pass it, refresh on a timer, and clear on logout:
async function syncAuth() {const token = await yourAuthProvider.getToken();await client.configure({auth: { jwt: token ? { token } : null },});}syncAuth();const refreshTimer = setInterval(syncAuth, 5 * 60 * 1000);// On logout:await client.reset();clearInterval(refreshTimer);Token refresh
JWT tokens expire. When a token expires and the widget needs to make a
request, the request will fail with invalid_token. To avoid this, refresh
the token on a timer (every 5 minutes is a good default) and after session
changes.
Failure behavior
When security is enabled, failures are explicit:
missing_token— no token was sentconfig_missing— App Security isn't configured yetconfig_invalid— the issuer or JWKS configuration has a probleminvalid_token— the token didn't pass verification or has expired
A token problem is usually one of three things: wrong issuer, wrong JWKS endpoint, or a token minted for the wrong audience.
Rollout checklist
Before you enforce authentication broadly:
- Confirm the app is pointing at the correct issuer and JWKS endpoint.
- Verify the widget actually receives the token.
- Verify the token audience matches
https://api.getuserfeedback.com. - Test one success and one failure on purpose.