Search code examples
javascriptangularidentityserver4openid-connect

Implementing isLoggedIn() function in Angular with oidc-client in *ngIf


Goal: I am attempting to hide and show a Loggin and Logout button in an Angular app using IdentityServer4 and oidc client.

Problem: The response from my isLoggedIn function returns undifined before it returns true and the *ngIf never shows the Logout button or hides the Login button. See code:

app.componenet.html:

<span>
      <button *ngIf="!isLoggedIn()" mat-button (click)="login()">Login</button>
      <button *ngIf="isLoggedIn()" mat-button (click)="logout()">Logout</button>
</span>

app.componenet.ts:

    isLoggedIn(){
        console.log('isLoggedIn -this._authService.isLoggedIn():',
          this._authService.isLoggedIn());
        this._authService.isLoggedIn();
      }

auth.service.ts

isLoggedIn(): boolean{
    return this._user && this._user.access_token && !this._user.expired;
  }

in auth.service.ts i set the user object like this:

 this._userManager = new UserManager(config);
    this._userManager.getUser().then(user =>{
      if(user && !user.expired){
        this._user = user;
      }

console.log output: enter image description here

What I've tried:

  1. I tried playing around with my version of oidc-client, switching between leatest and 1.4.1 and making sure that they match in package.json and my oidc-login-redirect.html file.
  2. Turning the auth.service.ts isLoggedIn function into a promise isLoggedIn() and calling it directly from *nfIf using an async pipe

auth.service.ts Promise{ return new Promise(resolve => { resolve(this._user && this._user.access_token && !this._user.expired); }); }

app.component.html

  <button *ngIf="!this._authService.isLoggedIn() | async" mat-button (click)="login()">Login</button>
  <button *ngIf="this._authService.isLoggedIn() | async" mat-button (click)="logout()">Logout</button>

Neither of these things has worked, and the promise attempt caused google chrome to hang up: enter image description here


Solution

  • If you are calling signinRedirectCallback in your Angular app somewhere (as opposed to a separate html page that lives outside your SPA), it is likely that your code setting this.user is being called prior to the signin callback bring invoked.

    You should subscribe to addUserLoaded on UserManager and set the user in your auth service from in the handler of that as well. That way your user will always be up to date.

    If the code above was copy/pasted from your source, your app.component isLoggedIn is not returning the value from the auth service, it is just calling isLoggedIn on the auth service but not returning the value.