jeroenheijmans/sample-angular-oauth2-oidc-with-auth-guards

The attempt at silent refresh during the runInitialLoginSequence method can cause extremely long page loads if no token is present depending on the server used

NickSt opened this issue · 2 comments

There should be a check to see if the access token is null before attempting the silent refresh near the end of the initial login script. Without it, the silent refresh will generate what is effectively a guaranteed to fail request that can take a long time since the server may never respond to it. Since this method directly blocks the initial page load it can delay the initial time load by a fairly long time (20-30 seconds) and cause some weird page reloading behavior.

The Demo server seems to handle it okay, but I attempted it on keycloak for instance and it made initial loads take 30 seconds until I added the null check. (other than that it mostly works great for keycloak btw, keycloak itself was the bigger bear in getting it to behave right.)

For example:
image

thanks for the demo project it has been very helpful too.

Thanks for the report, and glad the sample was helpful! (By the way, when you can, please copy paste code blocks instead of images, as code will help both with search and is nicer for visually impaired users.)

I'm curious to know what actually causes the 20-30 seconds delay, do you have any more details on that? What is the code waiting on? Are there any outstanding XHR calls from the top level frame or the iframe? What timeout or result causes the code to escape from the loop?

The reason I ask is because I think there might be valid situations where getAccessToken() returns null yet the silentRefresh() is still what you want. For example if there's still a valid cookie-based session with the Identity Provider but there is no access token, then the silent refresh should be used and return a new set of tokens, non?

Do you know if there's a public/demo instance of Keycloak somewhere that we can use for testing? If so I or someone else from the community could also chip in with research. I would love to know a bit more about the problem before we introduce your solution into the core of this sample.

Regardless, thanks for sharing your solution: if that works for you then that's already a win! Perhaps others landing here will also benefit from it?

@NickSt
I think you have the same problem like me. I deactivated the silentreresh and use the IFRAME variant from the IDServer (Keycloak).

export const authConfig: AuthConfig = new AuthConfig({
  responseType: 'code',
  scope: 'openid', // Ask offline_access to support refresh token refreshes

  sessionChecksEnabled: true,
  showDebugInformation: true, // Also requires enabling "Verbose" level in devtools

  requireHttps: false,

  useSilentRefresh: false,
});

You would also have to notice that your application is initialized twice.
I had now removed the following code block. But I'm not yet sure whether everything continues to work as before:

  return this.oauthService
          .silentRefresh()
          .then(() => Promise.resolve())
          .catch((result) => {

Is there a solution tested by the community? : D