繁体   English   中英

Angular AuthorizeGuard 角色

[英]Angular AuthorizeGuard Roles

我正在尝试在我的应用程序上实现基于角色的系统,并且我有以下内容:

授权.service.ts

  public isAuthenticated(): Observable<boolean> {
    return this.getUser().pipe(map(u => !!u));
  }

  public hasRole(roles: Array<string>): Observable<boolean> {
    return this.getUser().pipe(map(u => {
      if (!!!u) {
        return false;
      }
      const role = u['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'];
      return roles.some(r => r === role);
    }));
  }

app.routing.ts

...
  { path: 'list', component: ListComponent, canActivate: [AuthorizeGuard], data: { title: 'List', roles: [Role.Admin, Role.Developer, Role.Guest, Role.User]} }
...

我想在我的AuthorizeGuard上有以下逻辑:

如果未通过身份验证,请导航到登录页面。

如果已登录并具有所需的角色导航到该页面,否则导航到“禁止”页面。

我的 canActivate 上有这个代码:

  canActivate(
    _next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    this.authorize.isAuthenticated().subscribe(isAuthenticated => {
      if (isAuthenticated) {
        this.authorize.hasRole(roles).subscribe(hasRole => {
          if (hasRole) {
            return true;
          } else {
            this.router.navigate(['forbidden']);
          }
        });
      } else {
        this.router.navigate(ApplicationPaths.LoginPathComponents, {
          queryParams: {
            [QueryParameterNames.ReturnUrl]: state.url
          }
        });
      }
    });
    return true;
}

但由于订阅者,它不起作用。

无论如何要等待结果并返回它而不是总是返回true?

谢谢

您不能混合 2 订阅并最终返回 true,因为它始终为 true(最后返回)。

您需要从一开始就返回Observable<boolean>并将其链接到 Observable 为false || true 最后false || true

此代码在此编辑器中已更改,因此它可能从一开始就不起作用,但您会了解链接的想法

return this.authorize.isAuthenticated().pipe(
  concatMap(isAuth => isAuth ? this.authorize.hasRole(roles) : throwError('NO_AUTH')),
  concatMap(hasRole => hasRole ? of(true) : throwError('NO_ROLE')),
  catchError(error => {
    const isAuthError = error === 'NO_AUTH';
    if (isAuthError) {
      this.router.navigate(ApplicationPaths.LoginPathComponents, {
        queryParams: {
          [QueryParameterNames.ReturnUrl]: state.url
        }
      });
    } else {
      this.router.navigate(['forbidden']);
    }

    return of(false);
  }),
);

带有catchError的 ps 方法可以改写为其他方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM