【问题标题】:In Angular -> how to check if the user has permission using role-based access with the role save in the data base在Angular中->如何使用基于角色的访问权限检查用户是否具有权限,并将角色保存在数据库中
【发布时间】:2019-06-07 10:15:16
【问题描述】:

我正在尝试以 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;
  }

第三,我开发了函数 accessLoginToken,它将通过 httpclient.get 服务找到登录用户的角色,该服务返回一个数组,其中包含分配给用户的角色。示例{success: true, roles:['user']} 来自 auth.service.ts

 accessLoginToken(token: string) {
    const check = '/users/access';
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': 'Bearer ' + token,
      })
    };
    return this.http.get<any>('/api' + check, httpOptions).pipe(
      catchError(err => this.handleError('accessLoginToken', err))
    );
  }

function checkAccess 中的第四个,我将它与路由的那些进行比较,如果它们匹配,我允许访问,否则不允许访问。 来自 auth.guard.ts

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_token 这样的会话变量中的想法,所以我试图将它保存在数据库中......

对此主题的任何帮助将不胜感激..谢谢

【问题讨论】:

    标签: angular typescript role-base-authorization auth-guard role-based-access-control


    【解决方案1】:

    你是对的,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方法返回了一个observable,所以守卫会订阅observable并等待真假结果。

    【讨论】:

      【解决方案2】:

      您的问题在于您在 accessLoginToken 仍在运行时返回 this.hasAccess 。您可以将 observable 返回到 angular guard。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-08
        • 1970-01-01
        • 2019-04-30
        • 2015-11-20
        • 2014-02-03
        • 2020-09-13
        • 2021-03-31
        • 1970-01-01
        相关资源
        最近更新 更多