title: Oidc login infinite loop
body: <p>I'm using <strong>Auth0</strong> with <strong>Oidc</strong> in my Angular app for login.</p>
  
  <p>I have the following configurations:</p>
  
  <p><strong>auth.module</strong></p>
  
  <pre><code>NgOidcClientModule.forRoot({
        // prettier-ignore
        oidc_config: {
          authority: environment.sts.authority,
          client_id: environment.sts.clientId,
          redirect_uri: `${environment.appRoot}oidc-login-redirect-callback.html`,
          scope: 'openid profile',
          response_type: 'id_token token',
          post_logout_redirect_uri: `${environment.appRoot}oidc-logout-redirect-callback.html`,
          silent_redirect_uri: `${environment.appRoot}oidc-silent-renew-redirect-callback.html`,
          accessTokenExpiringNotificationTime: 10,
          automaticSilentRenew: true,
          metadata: {
            authorization_endpoint: `${environment.sts.authority}authorize?audience=${environment.sts.audience}`,
            userinfo_endpoint: `${environment.sts.authority}userinfo`,
            issuer: environment.sts.authority,
            jwks_uri: `${environment.sts.authority}.well-known/jwks.json`,
            // tslint:disable-next-line: max-line-length
            end_session_endpoint: `${environment.sts.authority}v2/logout?returnTo=${environment.appRootEncoded + 'oidc-logout-redirect-callback.html'}&amp;client_id=${environment.sts.clientId}`
          },
          userStore: new WebStorageStateStore({ store: window.localStorage })
        }
      })
  </code></pre>
  
  <p><strong>environment.ts</strong></p>
  
  <pre><code>export const environment = {
    production: false,
    appRoot: 'http://localhost:4200/',
    appRootEncoded: 'http://localhost:4200/',
    apiUrl: 'http://localhost:4201/',
    sts: {
      authority: 'https://dev-serj.eu.auth0.com/',
      clientId: 'R7fxgHNkPEj2VX1H7q4Fp0j2XnSqaudJ',
      audience: 'dev-serj-api'
    }
  };
  </code></pre>
  
  <p>In <strong>Auth0</strong>:</p>
  
  <p><strong>Allowed Callback URLs:</strong> </p>
  
  <ul>
  <li><a href="http://localhost:4200/oidc-login-redirect-callback.html" rel="nofollow noreferrer">http://localhost:4200/oidc-login-redirect-callback.html</a></li>
  <li><a href="http://localhost:4200/oidc-silent-renew-redirect-callback.html" rel="nofollow noreferrer">http://localhost:4200/oidc-silent-renew-redirect-callback.html</a></li>
  </ul>
  
  <p><strong>Allowed Web Origins</strong>: <a href="http://localhost:4200" rel="nofollow noreferrer">http://localhost:4200</a></p>
  
  <p><strong>Allowed Logout URLs</strong>: <a href="http://localhost:4200/oidc-logout-redirect-callback.html" rel="nofollow noreferrer">http://localhost:4200/oidc-logout-redirect-callback.html</a></p>
  
  <p>And the scripts from <strong>oidc HTML</strong> pages are the following ones:</p>
  
  <p><strong>oidc-login-redirect-callback.html</strong>:</p>
  
  <pre><code>&lt;script src="oidc-client.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
     var config = {
        userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
     };
     var mgr = new Oidc.UserManager(config);
     mgr.signinRedirectCallback().then(
        () =&gt; {
          window.history.replaceState({}, window.document.title, windows.location.origin);
          window.location = '/';
        }, error =&gt; {
            console.log(error);
        }
     );
  &lt;/script&gt;
  </code></pre>
  
  <p><strong>oidc-logout-redirect-callback.html</strong>:</p>
  
  <pre><code>&lt;script src="oidc-client.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
    var Oidc = window.Oidc;
    var config = {
      userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
    };
    if (Oidc &amp;&amp; Oidc.Log &amp;&amp; Oidc.Log.logger) {
      Oidc.Log.logger = console;
    }
    var isPopupCallback = JSON.parse(
      window.localStorage.getItem('ngoidc:isPopupCallback')
    );
    if (isPopupCallback) {
      new Oidc.UserManager(config).signoutPopupCallback();
    } else {
      new Oidc.UserManager(config).signoutRedirectCallback().then(test =&gt; {
        window.location.href = '/';
      });
    }
  &lt;/script&gt;
  </code></pre>
  
  <p><strong>oidc-silent-renew-redirect-callback.html</strong>:</p>
  
  <pre><code>&lt;script src="oidc-client.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
    var config = {
      userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
    };
    new Oidc.UserManager(config).signinSilentCallback().catch(function(e) {
      console.log(e);
    });
  &lt;/script&gt;
  </code></pre>
  
  <p>I'm also adding a <strong>Bearer token</strong> using an <strong>HTTP_INTERCEPTOR</strong>.</p>
  
  <p>In <strong>app.module</strong> I've created an <strong>initializeApp</strong> function:</p>
  
  <pre><code>export function initializeApp(appInitializerService: AppInitializerService) {
    return (): Promise&lt;void&gt; =&gt; {
      return appInitializerService.init();
    };
  }
  </code></pre>
  
  <p>which is used in <strong>APP_INITIALIZER</strong>:</p>
  
  <pre><code>providers: [
      AppInitializerService,
      {
        provide: APP_INITIALIZER,
        useFactory: initializeApp,
        deps: [AppInitializerService],
        multi: true
      }
    ],
  </code></pre>
  
  <p>And here I have the <strong>AppInitializerService</strong>:</p>
  
  <pre><code>@Injectable()
  export class AppInitializerService {
    constructor(private authService: AuthService) {}
  
    public async init(): Promise&lt;void&gt; {
      return new Promise(async resolve =&gt; {
        await this.authService.init();
  
        resolve();
      });
    }
  }
  </code></pre>
  
  <p>And my <strong>auth.service</strong> also:</p>
  
  <pre><code>@Injectable()
  export class AuthService {
    identity$: Observable&lt;User&gt;;
    loggedIn$: Observable&lt;boolean&gt;;
  
    constructor(private oidcFacade: OidcFacade) {
      this.identity$ = this.oidcFacade.identity$;
      this.loggedIn$ = this.oidcFacade.loggedIn$;
    }
  
    public init(): Promise&lt;void&gt; {
      this.oidcFacade.getOidcUser();
  
      return new Promise(resolve =&gt; {
        combineLatest([
          this.oidcFacade.waitForAuthenticationLoaded(),
          this.oidcFacade.loggedIn$
        ])
          .pipe(
            take(1),
            tap(([, loggedIn]) =&gt; {
              loggedIn ? resolve() : this.oidcFacade.signinRedirect();
            })
          )
          .subscribe();
      });
    }
  
    public signOut() {
      this.oidcFacade.signoutRedirect();
    }
  }
  </code></pre>
  
  <p>And I can't understand what I'm missing or why I'm into an infinite loop after I'm redirect to login:</p>
  
  <pre><code>http://localhost:4200/oidc-login-redirect-callback.html#access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik16ZzVPRFl5TkROQlJUVkNPRVEwTmpBNE1qUkZORGMxUVROQ1JqTkZOall4TVVJd1JqQTJRUSJ9.eyJpc3MiOiJodHRwczovL2Rldi1zZXJqLmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZTA1NDQzMTI4NGQ0NzBlYjkwZDkzNmEiLCJhdWQiOlsiZGV2LXNlcmotYXBpIiwiaHR0cHM6Ly9kZXYtc2Vyai5ldS5hdXRoMC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNTc3NTQ4OTYzLCJleHAiOjE1Nzc1NTYxNjMsImF6cCI6IlI3ZnhnSE5rUEVqMlZYMUg3cTRGcDBqMlhuU3FhdWRKIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSJ9.UGV6tEiAALfQg7qhO0lFBrC_3lZpzbLXBN9m1krWCi8kEF8w97FWOZ3P8l0p3Vdu1W8ZZGJ7WmED3YSyRNlq_pzVCYmE3T5szWNiEvj_MIisAFUmnwof3_KnPlNyES3zyqqowmDB-upIkMvqJNmEjdhl5svm3-b0b5mElSfQZSzkEjCII7ifPERstsHad2W5oORhlOSoqy01JRX4XfIO-cdwzoJK_RuRyMWCIuJ4UilV3aXg0wayeAG4bYMXBszrV1GSLtLkNiWjlMDstETIy0m_ngQRcZvLQf0tXFk2F1XbXyinW3sBdNkGPOmu0vWL0vxhAKmLFC2S0p2UKgKoDw&amp;scope=openid%20profile&amp;expires_in=7200&amp;token_type=Bearer&amp;state=2a91a1122b2e4d7687d96f8a40b1d066&amp;id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik16ZzVPRFl5TkROQlJUVkNPRVEwTmpBNE1qUkZORGMxUVROQ1JqTkZOall4TVVJd1JqQTJRUSJ9.eyJuaWNrbmFtZSI6InNlcmdpdS5pb251dDk4IiwibmFtZSI6IlNlcmdpdSBNb2xuYXIiLCJwaWN0dXJlIjoiaHR0cHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvMDIwMzAwZjFmZDgyNjA3NTI1NWFjOTRhMWM1ODRmMjY_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLmF1dGgwLmNvbSUyRmF2YXRhcnMlMkZzZS5wbmciLCJ1cGRhdGVkX2F0IjoiMjAxOS0xMi0yOFQxNDozMjoxNC40MzNaIiwiaXNzIjoiaHR0cHM6Ly9kZXYtc2Vyai5ldS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWUwNTQ0MzEyODRkNDcwZWI5MGQ5MzZhIiwiYXVkIjoiUjdmeGdITmtQRWoyVlgxSDdxNEZwMGoyWG5TcWF1ZEoiLCJpYXQiOjE1Nzc1NDg5NjMsImV4cCI6MTU3NzU4NDk2MywiYXRfaGFzaCI6IkN2OWFxdHJXbnIyR2RsZ2xkYjJNdHciLCJub25jZSI6ImIzMTkwMjliM2Y1NDQ3YjFiOWEwYWNjMzM0ODkyNjAxIn0.FbZuWPwn3zBNn_7hB6fYDQ45vyjyVKDXb3GOJFAI86eDC9I1cmzb3ugl8aGQybGirR60yAprRfNu7CfHiZ-4KfUAGItakG49i-NMzztedYAvA7ipiV7aWx4yA9_Y9PHKczD0NymnYj7U72vqkwnwvvJWk1f6eRx8e1cXZHAapGe9k-g5lazLAnrRAKXmw-75VyalPASRB3V9P59h0Ob-TyLwjCCDzIQxKnKPL9XvvYIcLocPNmDfj89Z1XBFeMTXHGiWfg2Swk9PnN6DucYMq-SYdSWIb3CgtOJ-R1HCK7iSsR0lQFnCVnmPTwr_HovwQoFqqFydSCUXxUOeRAYkAQ
  </code></pre>