Tokens Renewal

Many OpenID Connect adapters, end up implementing token renewal with a background refresh loop. That approach often creates avoidable load and some tricky edge cases. With oidc-spa, token lifecycle management is handled for you and stays out of your app code.


The Problem With Access Token Refresh Loops

Access tokens are meant to be short-lived (typically ~5 minutes, but sometimes as little as 20 seconds for high-security apps). Many adapters try to keep an access token “always fresh” in cache, which leads to:

  • Constant background refreshes

  • Heavy load on your auth server

  • Agravated load when mutiple tabs are open on your app.

This isn’t needed. You don’t need a valid access token cached at all times.


The Better Approach (What oidc-spa Does)

Whenever you need to make an authenticated request, just ask oidc-spa for a token:

const oidc = await getOidc();

if (!oidc.isUserLoggedIn) {
    throw Error("Logical error in our application flow");
}

const { accessToken } = await oidc.getTokens();
headers.set("Authorization", `Bearer ${accessToken}`);
  • If a valid token is cached, you’ll get it.

  • If it’s expired or soon to expire, oidc-spa silently refreshes it using the refresh token.

Example: interceptor pattern Example: custom fetch

But what about session expiration?

Behind the scenes, oidc-spa ensures the session never expires prematurely by refreshing at least once before the refresh token itself expires. This prevents the backend from destroying the session simply because the user wasn’t making authenticated requests (e.g., they’re filling out a form or browsing content).

At the same time, oidc-spa tracks actual user activity (keyboard, mouse, touch). If the user is truly idle beyond the refresh token lifespan, they’re logged out as expected.


Why oidc-spa Still Exposes renewTokens()

There are two legitimate edge cases:

  1. After custom requests: If you make a request to your OIDC server that changes claims in the id_token or access_token, call renewTokens() to ensure you have the latest values. (This is a rare use case. It usually happens when user info is updated outside your app. If you’re not sure, you can generally assume you don’t need this.)

  2. Getting a freshly issued token: If at one point in time, you want to be sure that you have a freshly issued token with it's maximum lifetime you might want to call renewTokens() before you call getTokens()

  3. Custom token parameters: If your OIDC server supports extra token endpoint params, you can trigger a refresh with them. (extraTokenParams is also available at createOidc() time.)

Outside of these rare cases, you never need to call renewTokens() manually.

Last updated

Was this helpful?