【问题标题】:Angular Firebase Guards, block routing with specific rolesAngular Firebase Guards,阻止具有特定角色的路由
【发布时间】:2019-10-02 22:11:42
【问题描述】:

您好 Angular 开发人员,

我需要你的帮助,我需要阻止具有特定角色的路由,这是我的个人资料文档:

我的角度守卫返回并反对配置文件:{admin: true, current: false}

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class RoleGuard implements CanActivate {

  constructor(
    public authService: AuthService,
    public router: Router
  ) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<any> | boolean {

    return this.authService.getAuthWithProfile().pipe(
      map((data) => {
        const roles = data.roles;
        return roles; // This returns   {admin: true, current: false}
      })
    );

   }
  }

问题是如何在 Angular Routing 中实现角色的守卫,例如:

{ path: 'tasks', component: TasksComponent, canActivate: [RoleGuard] },

【问题讨论】:

  • data.roles的属性是什么意思?根据您的示例,您希望导航继续还是被阻止?您是否还有附加到用于决定守卫的路线的数据?
  • 感谢亚历山大的回复。在该属性中分配给用户的 2 个角色,即 {admin: true, current: false},我希望阻止导航,具体取决于道具中的角色
  • 好的,在你的例子中这个守卫,需要存在什么角色并且为真才能继续导航?使用这个守卫的所有路由都使用相同的逻辑吗?您是否为每条路线设置了多个警卫来检查不同的特定角色?
  • 例如如果 admin 为 true,对于这条路由 { path: 'admin, component: AdminComponent, canActivate: [RoleGuard] },我应该以管理员身份访问该路由。这个想法是看守检查多个角色。谢谢亚历山大
  • 这是个问题。如果您对需要不同角色的不同路线使用相同的警卫,那么您如何匹配它。您是否提前知道路由配置中每条路由所需的确切角色,这些角色是静态的吗?这个管理员路由如何始终使用相同的角色,或者它是来自某个数据源的动态?

标签: angular angular-routing angularfire angular-guards


【解决方案1】:

一种方法是使用Routedata 属性。您可以将自定义值附加到任何给定的路由。在您的示例中,您可以创建一个名为roles 的属性,该属性可用于您的canActivate()。在以下示例中,将一组角色添加到 TasksComponent 的路由中。在警卫中,我们可以从 next.data.roles 中提取 roles,然后检查从 Firebase 返回的角色是否存在且处于活动状态:

路线:

{
  path: 'tasks',
  component: TasksComponent,
  data: {
    roles: ['admin', 'subscriber']
  }
  canActivate: [RoleGuard]
}

后卫:

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | boolean {
  const routeRoles = next.data && next.data.roles; // ['admin', 'subscriber']

  return this.authService.getAuthWithProfile().pipe(
    map((data) => {
      const roles = data.roles; // { admin: true, current: false }
      const activeRoles = Object.entries(roles).filter(([role, isActive]) => isActive).map(([role, isActive]) => role); // ['admin']

      return routeRoles.some(routeRole => activeRoles.includes(routeRole)); // true
    })
  );

  }
}

路由上的data.roles 不必是一个数组,它可以是一个对象,您可以以您喜欢的任何方式检查激活的路由是否存在。例如,如果只有一个角色:

{
  path: 'tasks',
  component: TasksComponent,
  data: {
    role: 'admin'
  }
  canActivate: [RoleGuard]
}

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | boolean {
  const routeRole = next.data && next.data.role; // 'admin'

  return this.authService.getAuthWithProfile().pipe(
    map((data) => {
      const roles = data.roles; // { admin: true, current: false }
      const activeRoles = Object.entries(roles).filter(([role, isActive]) => isActive).map(([role, isActive]) => role); // ['admin']

      return routeRoles.includes(routeRole); // true
    })
  );

  }
}

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多