Change or extend access

Use this page to update what a user can access (change permissions) or to keep their session alive by refreshing a token before it expires (extend access).

Before you start​

Confirm you have:

Change a user's permissions​

To add or remove a user's access to resources, grant a new token with the updated resource list and return it to the client.

  1. On your server, call grantToken with the updated resources for the user. See Grant, change, and revoke permissions.
  2. Return the new token to the client.
  3. On the client, call setToken with the new token. See Initialize a client SDK with an auth key.

The client uses the new token on its next request. The old token remains valid until its TTL expires or you revoke it.

Extend access before a token expires​

To keep a user's session active, refresh the token before it expires. The core approach is the same as changing permissions: grant a new token and push it to the client. Three strategies for when and how to do this are listed below.

Strategy 1: Server-side proactive refresh​

The server tracks the expiry time of each token it issues. Before a token expires, the server requests a new grant and pushes the token to the client. The client sets the new token when it receives it.

Best for: apps where the server has a persistent connection to clients (for example, via a WebSocket or PubNub channel).

Strategy 2: Client-side TTL timer​

The client calculates when the token expires from the timestamp and ttl fields returned by parseToken, and sets a timer to request a refresh before that time. When the timer fires, the client calls your server's token refresh endpoint. The server grants a new token and returns it. The client sets it with setToken.

Best for: apps where the client drives the session lifecycle.

1const REFRESH_BUFFER_MS = 60 * 1000;
2const MAX_RETRY_DELAY_MS = 60 * 1000;
3const MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
4
5let currentToken = null;
6let refreshTimer = null;
7let refreshInFlight = null;
8let retryDelayMs = 1000;
9
10function scheduleTokenRefresh(token) {
11 currentToken = token;
12 clearTimeout(refreshTimer);
13
14 // timestamp is the issue time in Unix seconds; ttl is in minutes.
15 const { timestamp, ttl } = pubnub.parseToken(token);
show all 56 lines

Adapt fetchTokenFromYourServer() to your server's token API. The example behaves as follows:

  • Expiry time. A token expires ttl minutes after timestamp, not ttl minutes after the client receives it. timestamp is in Unix seconds and ttl is in minutes, so (timestamp + ttl * 60) * 1000 gives the expiry time in milliseconds, the unit Date.now() uses.
  • Buffer. The refresh starts REFRESH_BUFFER_MS before expiry, or at half the token's lifetime for tokens shorter than twice the buffer. timestamp comes from PubNub, while Date.now() comes from the device clock, so clock skew between the two shifts the refresh time. If device clocks in your audience can be off by more than a few seconds, increase the buffer to cover that skew and the time your refresh request takes.
  • Overdue tokens. If the token is already past its refresh time, for example because the app loaded a stored token, the refresh starts immediately.
  • Resume. When the tab becomes visible again, the client recalculates the delay from the current time, so a timer that the browser paused doesn't fire late. In React Native or other non-browser clients, call scheduleTokenRefresh(currentToken) from your app's resume event instead of visibilitychange.
  • One refresh at a time. refreshInFlight holds the pending request, so a resume event during a refresh doesn't start a second one.
  • Errors. A failed refresh retries with exponential backoff, capped at MAX_RETRY_DELAY_MS. The client keeps its current token until a refresh succeeds.
  • Long-lived tokens. setTimeout can't wait longer than MAX_TIMER_DELAY_MS (about 24.8 days), so the example re-checks at that interval for tokens with a longer lifetime.

Strategy 3: Just-in-time on 403​

The client handles 403 responses by requesting a new token from the server, setting it with setToken, calling reconnect(), and retrying the failed request.

Best for: simpler apps where occasional brief access interruptions are acceptable. This strategy reacts to failures rather than preventing them.

Reconnect after setting a token

When you set a new token after receiving a 403, call pubnub.reconnect() (name may vary across SDKs) before retrying the request. Without reconnecting, the SDK may continue using the expired or revoked token.

Was this page useful?

Last updated on