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

  1. Enable App Security in your getuserfeedback.com settings.
  2. Configure your issuer and JWKS endpoint.
  3. 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

TypeScriptget-user-feedback-auth.tsx
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:

TypeScriptauth.ts
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 sent
  • config_missing — App Security isn't configured yet
  • config_invalid — the issuer or JWKS configuration has a problem
  • invalid_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:

  1. Confirm the app is pointing at the correct issuer and JWKS endpoint.
  2. Verify the widget actually receives the token.
  3. Verify the token audience matches https://api.getuserfeedback.com.
  4. Test one success and one failure on purpose.