首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Angular7 AuthGuard Firebase索赔

Angular7 AuthGuard Firebase索赔
EN

Stack Overflow用户
提问于 2019-03-22 15:53:37
回答 2查看 1.1K关注 0票数 0

我可以使用防火墙登录,但在我的应用程序中,我有3个级别的用户。我们叫他们管理员,用户,编辑。我在Firebase提供的自定义声明中保留用户的角色。

在AuthGuard中,我传递数据expectedRoles = ['admin', 'editor'],添加希望允许特定路由的角色。并且我想重定向到自己的页面,比如尝试管理路径的编辑器将返回到编辑器仪表板。

这是我的AuthGuard的canActivate函数:

代码语言:javascript
运行
复制
return this.auth.user.pipe(
  map(user => {
    if (user) {
      user.getIdTokenResult().then((idTokenResult) => {
        if (idTokenResult.claims.admin) {
          if (expectedRoles.indexOf('admin') > -1) {
            return true;
          } else {
            // return back to admin dashboard
            this.router.navigate(['/admin']);
          }
        } else if (idTokenResult.claims.editor) {
          if (expectedRoles.indexOf('editor') > -1) {
            return true;
          } else {
            // return back to editor dashboard
            this.router.navigate(['/editor']);
          }
        } else if (idTokenResult.claims.user) {
          if (expectedRoles.indexOf('user') > -1) {
            return true;
          } else {
            // return back to user dashboard
            this.router.navigate(['/user']);
          }
        } else {
          // Unexpected claim, better logout, TODO; display something
          this.router.navigate(['/auth/logout']);
        }
      });
    } else {
      // User is not authenticated
      // Check if we are expecting a guest
      if (expectedRoles.indexOf('guest') > -1) {
        return true;
      } else {
        this.router.navigate(['/auth/login']);
      }
    }
  })
).first();

在添加user.getIdTokenResult().then(...)之前,它运行得很好,我知道这可能是因为没有等待异步调用来解析自定义声明。我怎么才能解决这个问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-22 15:56:46

使用switchMap代替地图,生成函数async并等待结果。switchMap接受async函数返回的承诺。然后在内部您可以使用await

代码语言:javascript
运行
复制
return this.auth.user.pipe(
  // switchMap instead of map
  // async function call
  switchMap(async (user) => {
    if (user) {
      // await here
      await user.getIdTokenResult().then((idTokenResult) => {
        if (idTokenResult.claims.admin) {
          if (expectedRoles.indexOf('admin') > -1) {
            return true;
          } else {
            // return back to admin dashboard
            this.router.navigate(['/admin']);
          }
        } else if (idTokenResult.claims.editor) {
          if (expectedRoles.indexOf('editor') > -1) {
            return true;
          } else {
            // return back to editor dashboard
            this.router.navigate(['/editor']);
          }
        } else if (idTokenResult.claims.user) {
          if (expectedRoles.indexOf('user') > -1) {
            return true;
          } else {
            // return back to user dashboard
            this.router.navigate(['/user']);
          }
        } else {
          // Unexpected claim, better logout, TODO; display something
          this.router.navigate(['/auth/logout']);
        }
      });
    } else {
      // User is not authenticated
      // Check if we are expecting a guest
      if (expectedRoles.indexOf('guest') > -1) {
        return true;
      } else {
        this.router.navigate(['/auth/login']);
      }
    }
  })
).first();

这只是一个与此解决方案无关的提示--比在AuthGuard函数中加载令牌声明更好,您应该在用户登录后加载它,并以从登录响应存储信息的方式将其存储在存储中。这样会快得多。

票数 2
EN

Stack Overflow用户

发布于 2019-03-22 15:58:45

尝试使用rxjs管道进行内部可观察的调用: flatMap和flatMapTo或mergeMap或mergeMapTo。在您的具体案例中,我认为mergeMap是最好的选择。

请随意阅读rxjs中的那些管道,它们可能是解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55303417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档