Reputation: 81
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?
Upvotes: 5
Views: 10837
Reputation: 814
I had the same issue. I need to revoke the token on addAccessTokenExpiring
event.
useEffect(() => {
return auth.events.addAccessTokenExpiring(() => {
auth.revokeTokens();
})
}, [auth.events]);
My authentication server is IdentityServer3. I am using a React app (with React-Router-6) as a client with a .Net 6 Web Api using 'Access Token' to get data from an 'authorized' end-point.
If you need more clarification/code, let me know.
Upvotes: 1