I have been trying to get silent token refreshes to work using react-oidc-context. This package is built on top of oidc-client-ts. My application uses react-router. By default silent token renewal is turned on with react-oid-context. With this setup, the page reloads about a minute before the token expires - not a great user experience. The token does get renewed - the new token with a new expiration date is stored in session storage, which I believe is the source of truth for calls to get the token from react-oidc-context.
My understanding is that, to perform a silent token renewal, oidc-client-ts attaches an iframe to the page and loads a page inside it from your authority / authentication provider. This does not occur with the default setup for react-oidc-context. I can get it to work, partially, by sidestepping the react app: by pointing the silent_redirect_uri config variable to a page outside the react app and triggering the logic for the silent token renewal in that page. The basic idea is described here:
My config for react-oidc-context:
const oidcConfig = {
client_id: <AUTH_LOCK_KEY>,
redirect_uri: window.location.origin + '/loading-handler',
silent_redirect_uri: window.location.origin + '/silent-renew',
authority: <SSO_URL>,
automaticSilentRenew: true,
onSigninCallback,
}
My script at /silent-renew/index.html:
<script src="oidc-client.min.js"></script>
<script>
function inIframe() {
try {
return window.self !== window.top
} catch (e) {
return false;
}
}
if (inIframe()) {
console.log("in iframe")
} else {
console.log("not in iframe")
}
new Oidc.UserManager({
authority: <SSO_URL>,
client_id: <AUTH_LOCK_KEY>,
redirect_uri: window.location.origin,
}).signinSilentCallback().then(r => console.log(r))
</script>
This works up to a point. There is no page refresh, a page loads in the iframe, and a call goes out to the authority which returns a HTTP 200. There seems to be a token in a set-cookie from the server. However, the token in local session storage doesn't update. Also, oidc-client-ts keeps trying every 30 seconds or so to perform the silent renewal. So, how can I refresh the token without a page refresh?