Angular 角度->;如何使用数据库中保存的角色检查用户是否具有使用基于角色的访问权限

Angular 角度->;如何使用数据库中保存的角色检查用户是否具有使用基于角色的访问权限,angular,typescript,role-base-authorization,auth-guard,role-based-access-control,Angular,Typescript,Role Base Authorization,Auth Guard,Role Based Access Control,我正在尝试在angular中对我的应用程序进行基于角色的访问,我需要一些帮助,因为我是angular中的新手 首先,这是我在路径中所拥有的,在这里我确定哪些角色可以访问它 从app-routing.module.ts { path: 'profile', component: ComunityComponent, canActivate: [AuthGuard], data: { allowedRoles: ['admin', 'user'] } }, 其次,我使用

我正在尝试在angular中对我的应用程序进行基于角色的访问,我需要一些帮助,因为我是angular中的新手

首先,这是我在路径中所拥有的,在这里我确定哪些角色可以访问它

从app-routing.module.ts

{
  path: 'profile',
  component: ComunityComponent,
  canActivate: [AuthGuard],
  data: {
    allowedRoles: ['admin', 'user']
  }
},
其次,我使用canActivate功能检查用户是否可以访问路由。 来自auth.guard.ts

private hasAccess: boolean;

constructor(private router: Router, private auth: AuthService) {}

canActivate(next: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const allowedRoles = next.data.allowedRoles;
    if (localStorage.getItem('currentUser')) {
      return this.checkAccess(localStorage.getItem('currentUser'), allowedRoles);
    }

    this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
    return false;
  }
private checkAccess(token: string, allowedRoles: string[]): boolean {
    this.hasAccess = false;
    this.auth.accessLoginToken(token).subscribe(data => {
      if (data.success) {
        data.roles.forEach(rol => {
          if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
            this.hasAccess = true;
          }
        });
      }
    }, (error) => {
      console.log(error);
    });
    console.log(this.hasAccess);
    return this.hasAccess;
  }
第四,在
功能checkAccess
中,我将其与路线的比较,如果它们匹配,我允许访问,否则不允许。 来自auth.guard.ts

private hasAccess: boolean;

constructor(private router: Router, private auth: AuthService) {}

canActivate(next: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const allowedRoles = next.data.allowedRoles;
    if (localStorage.getItem('currentUser')) {
      return this.checkAccess(localStorage.getItem('currentUser'), allowedRoles);
    }

    this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
    return false;
  }
private checkAccess(token: string, allowedRoles: string[]): boolean {
    this.hasAccess = false;
    this.auth.accessLoginToken(token).subscribe(data => {
      if (data.success) {
        data.roles.forEach(rol => {
          if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
            this.hasAccess = true;
          }
        });
      }
    }, (error) => {
      console.log(error);
    });
    console.log(this.hasAccess);
    return this.hasAccess;
  }
主要问题是,我无法让httpclient订阅将hasAccess变量的值更改为true以允许访问。即使代码
this.hasAccess=true时,函数返回false

顺便说一下,我不喜欢这个主意​​将角色保存在会话变量(如access_令牌)中,以便我尝试将其保存在数据库中


在这个问题上的任何帮助都将不胜感激。。谢谢

您是正确的,
checkAccess
函数在异步api调用完成之前完成,因此总是返回
false
。相反,您应该将observable传递给canActivate方法

private checkAccess(token: string, allowedRoles: string[]): boolean {
    this.hasAccess = false;
    return this.auth.accessLoginToken(token).pipe(
        map(data => {
            if (data.success) {
                data.roles.forEach(rol => {
                    if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
                        this.hasAccess = true;
                    }
                });
            }
            return this.hasAccess;
        })
    )
}

因为一个可观察对象被返回到
canActivate
方法,所以警卫将订阅该可观察对象并等待一个正确或错误的结果。

您的问题在于,您在accessLoginToken仍在运行时返回了this.hasAccess。你可以返回一个可观察到的角度保护