---
title: "Client authentication and JWT session renewal | Nutrient"
canonical_url: "https://www.nutrient.io/guides/web/viewer/client-authentication/"
md_url: "https://www.nutrient.io/guides/web/viewer/client-authentication.md"
last_updated: "2026-05-23T00:08:18.195Z"
description: "Learn how to refresh short-lived JWTs in server-backed Nutrient Web SDK sessions using onAuthFailed and setSession."
---

# Client authentication and session renewal

When you use Nutrient Web SDK with [Document Engine](https://www.nutrient.io/guides/document-engine.md) in server-backed mode, the viewer is authenticated with a JSON Web Token (JWT). For short-lived JWTs, you can refresh authentication at runtime without unloading and reloading the viewer.

## Runtime JWT refresh API contract

- [`NutrientViewer.Configuration#onAuthFailed`](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html#onAuthFailed) has the signature `() => void | Promise<void>`.

  - It receives no arguments.
  - Inside this callback, fetch a fresh JWT and call `instance.setSession(newJwt)`.

- [`NutrientViewer.Instance#setSession`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#setSession) has the signature `setSession(session: string): void`.

  - Pass a raw JWT string.
  - Do not pass `{ jwt:... }` or an `authPayload` object.

## Reactive refresh: onAuthFailed + setSession

Use this pattern when a request fails due to expired or invalid authentication:

```js

let instance;

instance = await NutrientViewer.load({
  container: "#viewer",

  serverUrl: "https://your-document-engine.example.com",
  documentId: "your-document-id",
  authPayload: { jwt: initialJwt },
  onAuthFailed: async () => {
    const newJwt = await fetchNewJwtFromBackend();
    if (!instance) {
      throw new Error("Viewer instance is not available yet.");
    }

    instance.setSession(newJwt);
  },
});

```

`onAuthFailed` is configured at `load()` time and doesn’t receive the `instance`. Use a closure or mutable reference (as shown above) so the callback can call `setSession` on the current instance.

If `setSession()` isn’t called within 30 seconds while handling an auth failure, the refresh times out and the affected requests fail.

## Proactive refresh: Call setSession before expiry

If you know JWT expiry time in advance, refresh before the token expires:

```js

function parseJwtExp(jwt) {
  const [, payload] = jwt.split(".");
  return JSON.parse(atob(payload)).exp;
}

function scheduleJwtRefresh(instance, jwt) {
  const exp = parseJwtExp(jwt);
  const refreshBuffer = 5 * 60 * 1000; // Refresh 5 minutes early.
  const timeout = Math.max(exp * 1000 - Date.now() - refreshBuffer, 0);

  setTimeout(async () => {
    const newJwt = await fetchNewJwtFromBackend();
    instance.setSession(newJwt);

    // Schedule the next proactive refresh.
    scheduleJwtRefresh(instance, newJwt);
  }, timeout);
}

```

This keeps the same viewer instance alive while rotating session tokens.

## Expected behavior during refresh

- If the token refresh succeeds, the current viewer session stays active and document operations continue without reloading the instance.

- If the refresh fails or times out, requests that require authentication fail and the user may need to retry after your app obtains a fresh JWT.

## Mode limitations

- This flow is supported only in server-backed mode.

- It isn’t supported when `useDeprecatedRestProvider` is enabled.

- Calling `setSession()` in standalone mode is unsupported and only logs a warning.
---

## Related pages

- [Embed Web SDK in a dashboard/app shell](/guides/web/viewer/embed-in-dashboard-app-shell.md)
- [JavaScript image viewer library](/guides/web/viewer/images.md)
- [Enhance PDF viewing with linearized downloading](/guides/web/viewer/linearized-downloads.md)
- [Create custom annotation toggle button](/guides/web/viewer/custom-annotation-toggle.md)
- [JavaScript PDF viewer library](/guides/web/viewer.md)
- [Page layout and scroll options in our JavaScript PDF viewer](/guides/web/customizing-the-interface/document-presentation-options.md)
- [Mobile responsive JavaScript PDF viewer](/guides/web/viewer/mobile-responsive.md)
- [Office document viewing in JavaScript](/guides/web/viewer/office-documents.md)
- [JavaScript Support in our PDF viewer](/guides/web/features/javascript.md)
- [JavaScript PDF viewer library](/guides/web/viewer/pdf.md)
- [Enable or disable permissions in our JavaScript viewer](/guides/web/features/document-permissions.md)
- [PDF document streaming in JavaScript](/guides/web/viewer/streaming.md)
- [macOS/Linux](/guides/web/viewer/troubleshooting.md)
- [Zoom options in our JavaScript PDF viewer](/guides/web/viewer/zooming.md)

