【问题标题】:Angular AuthGuard canActivate with observable from promise not workingAngular AuthGuard canActivate with observable from promise not working
【发布时间】:2020-11-21 19:32:27
【问题描述】:

我正在尝试保护 Angular 中的管理面板,以便只有管理员用户可以访问它。在创建管理员 AuthGuard 时,我遇到了一个问题,当逻辑比“用户是否登录?”更复杂一点时,AuthGuard 似乎不起作用。

我得到一个空白屏幕,而不是预期的重定向。

在过去的几个小时里,我一直在努力寻找根本原因,但它似乎卡在了这条线上:const user = await this.firebaseAuth.user.toPromise();,但我不明白为什么。

有人能指引我正确的方向吗,因为我似乎迷失在 Angular 和 Observables 的丛林中?

AuthGuard canActivate 方法:

canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.accountDataService.userIsAdmin().pipe(
      take(1),
      map((admin) => {
        console.log(admin);

        if (admin) {
          return true;
        }

        this.router.navigate(['/aanmelden']);
        return false;
      })
    );
  }

这是数据服务:

userIsAdmin(): Observable<boolean> {
    return from(
      new Promise<boolean>(async (resolve) => {
        const user = await this.firebaseAuth.user.toPromise();

        if (user === undefined) {
          resolve(false);
        }

        const result = await user.getIdTokenResult();
        const admin = result.claims.admin;

        if (admin === undefined || admin === null || admin === false) {
          resolve(false);
        }

        resolve(true);
      })
    );
  }

【问题讨论】:

  • 不熟悉 firebase API 但this.firebaseAuth.user.toPromise() 可以拒绝和解决吗?如果是这样,您需要将其包装在 try/catch 中或使用 .catch()
  • @WillTaylor 我已经将它包装在 try catch 中,但它不会抛出错误,它只是卡在该行。

标签: angular rxjs auth-guard


【解决方案1】:

我猜this.firebaseAuth.user 没有完成。 toPromise 仅在 observable 完成时才解析。

您应该重写您的 userIsAdmin 函数以仅使用 observables。

userIsAdmin(): Observable<boolean> {
  return this.firebaseAuth.user.pipe(
    switchMap(user => {
      if (user === undefined || user === null) {
        return of(false);
      }

      return from(user.getIdTokenResult()).pipe(
        map(result => {
          const admin = result.claims.admin;

          if (admin === undefined || admin === null || admin === false) {
            return false;
          }

          return true;
        })
      )
    })
  );
}

【讨论】:

    【解决方案2】:

    observable 需要完成。最后,我在.take(1) 上取得了更大的成功。这可以解释为什么Observable.of(true) 有效。 试试这个:

    canActivate(): Observable<boolean> {
      return this.auth.map(authState => {
        if (!authState) this.router.navigate(['/aanmelden']);
        console.log('activate?', !!authState);
        return !!authState;
      }).take(1)
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-01
      • 2018-12-22
      • 2014-11-21
      • 2022-12-28
      • 2019-01-11
      • 2022-11-20
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      相关资源
      最近更新 更多