Skip to content

Refresh and Logout

Keycloak manages three related concepts that control how long a user stays logged in:

ConceptTypical defaultWhat it controls
Access token lifespan5 minutesHow long the JWT is valid before the backend rejects it
Refresh token lifespan30 minutes (SSO Session Idle)How long a refresh token can be used to get new access tokens
SSO session max10 hoursAbsolute maximum session length, even with active refresh

When the access token expires, the frontend should use the refresh token to silently get a new one — without forcing the user to log in again. When the SSO session expires, the user must re-authenticate.

keycloak.updateToken(minValidity) is the idiomatic way to handle refresh in keycloak-js. Call it before any API request; if the current access token will expire within minValidity seconds, keycloak-js silently exchanges the refresh token for a new access token:

// Refresh the token if it expires within 60 seconds,
// then call the API with the fresh token.
async function callApi(path) {
  try {
    await keycloak.updateToken(60);
  } catch {
    // Refresh token has expired — force re-login.
    keycloak.login();
    return;
  }

  const response = await fetch(`https://api.example.com${path}`, {
    headers: { Authorization: `Bearer ${keycloak.token}` },
  });
  return response.json();
}

If updateToken rejects (the refresh token is expired or revoked), the user’s session is gone and you should redirect them to login with keycloak.login().

Calling a local “clear state” function in your app is not enough. The user’s SSO session still exists in Keycloak, which means they could immediately access other apps in the same realm without re-authenticating — or even return to your app and bypass the login screen.

A proper logout hits Keycloak’s end-session endpoint. keycloak-js does this for you:

// Redirect to Keycloak's end-session endpoint,
// then back to your app's home page.
keycloak.logout({ redirectUri: 'https://app.example.com/' });

Under the hood this redirects the browser to:

/realms/{realm}/protocol/openid-connect/logout
?id_token_hint=<id_token>
&post_logout_redirect_uri=https://app.example.com/

Keycloak clears the SSO session cookie, marks the refresh token as revoked, and redirects back to your app.

ActionClears local tokenClears Keycloak session
Local state reset onlyYesNo
keycloak.logout()YesYes
What does keycloak.updateToken(60) do?
What should your app do when keycloak.updateToken() rejects (throws)?
Why is clearing local app state alone insufficient for logout?
What does the SSO Session Idle timeout control?