angularangular-routingangular-route-guards

angular authguard redirecting to /


i've changed my authguard to fetch the user object if it is empty. i'm just storing the token in the storage. i see the console.log "role and user ok" and the correct url /member but it redirects me always to / and not to /member in my case.

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.loggedin) {
      if (!this.authService.user) {
        console.log('get user')
        this.authService.getUser().pipe(first()).subscribe((result: any) => {
          console.log(result.user)
          if (route.data.roles && route.data.roles.indexOf(result.user.role.name) === -1) {
            console.log('wrong role')
            this.router.navigate(['/']);
            return false;
          } else {
            console.log('role and user ok')
            console.log(state.url)
            return true;
          }
        });
      } else {
        console.log(this.authService.user)
        console.log('user already set')
        if (route.data.roles && route.data.roles.indexOf(this.authService.user.role.name) === -1) {
          console.log('WRONG ROLE')
          this.router.navigate(['/']);
          return false;
        } else {
          console.log('user and role ok')
          return true;
        }
      }

    } else {
      console.log('redirect to login')
      this.router.navigate(['/login']);
      return false;
    }
  }

AuthService

 public isLoggedIn() {
    if (localStorage.getItem('token')) {
      return true;
    } else {
      return false;
    }
  }

getUser() {
    return this.http.get<any>(environment.apiUrl + '/user').pipe(
      tap(res => this.setSession(res))
    );
  }

thanks


Solution

  • Your problem lies here

    this.authService.getUser().pipe(first()).subscribe((result: any) => {
              console.log(result.user)
              if (route.data.roles && route.data.roles.indexOf(result.user.role.name) === -1) {
                console.log('wrong role')
                this.router.navigate(['/']);
                return false;
              } else {
                console.log('role and user ok')
                console.log(state.url)
                return true;
              }
            });
    

    You are subscribing to the pipe, so that is asynchronous, the code flow does not wait for that to return and moves ahead and does not find any value true or false. Basically get rid of the asyc subscribe call and you will be fine, that makes me question why do you want to pipe() it in the first place.