如何在Angular中按用户角色阻止操作

时间:2019-08-07 17:17:31

标签: angular security angular-guards

我已经有一个AuthService可以对登录用户进行身份验证,而AuthGuard可以阻止未登录的用户访问。

某些页面我限制了UserProfile / Role的访问,但是现在我需要阻止页面上的操作。

我从大到小都有“管理员,经理,支持和代理”之类的角色。

如何仅将级别设置为“经理”或“更高”来编辑所有人都可以访问的页面上的内容(支持和代理只能查看)?

这是我当前的canActivate方法:

canActivate(route: ActivatedRouteSnapshot) {

  const currentUser = JSON.parse(localStorage.getItem('currentUser'));
  if (currentUser) {
    // check if route is restricted by role
    if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
      // role not authorised so redirect to home page
      this.router.navigate(['/']);
      return false;
    }
    // authorised so return true
    return true;
  }
  // not logged in so redirect to login page
  this.router.navigate(['auth/login']);
  return false;
}

这是我的模块routing.module.ts

const routes: Routes = [{
  path: '',
  component: ReportsComponent,
  canActivateChild: [AuthGuard],
  children: [
    {
      path: 'blocked-users',
      component: BlockedUsersComponent,
      data: { roles: [Role.admin, Role.manager, Role.suporte, Role.agent] },
      children: [
        { ... 

需要修复以下两个主题:

1)第data: { roles: [] }行,我只想通过较低的级别(例如Agent);

2)内部组件告知只有Manager可以编辑数据(如果Role == Support或Agent,则只能编辑按钮disable

1 个答案:

答案 0 :(得分:2)

将您的授权代码分解为一项服务,您的警卫和其他服务都可以使用(DRY!)。从那里开始,检查整个站点角色的逻辑是相同的。

@Injectable()
export class RoleAuthorisationService {
  public isAuthorised(roles: Role[]): boolean {
    const currentUser = JSON.parse(localStorage.getItem('currentUser'));
    if (!currentUser) return false;
    return roles.indexOf(currentUser.role) >= 0)
  }
}

警卫将使用它,但是您可以通过对授权服务进行自己的检查来阻止使用页面的任何部分。

您的警卫(非常近似,因为现在是23:32,我想去睡觉):

export class YourGuard {

  constructor(private readonly auth: RoleAuthorisationService) {}

  canActivate(route: ActivatedRouteSnapshot) {
    if (route.data.roles && !this.auth.isAuthorised(route.data.roles)) {
      // role not authorised so redirect to home page
      this.router.navigate(['/']);
      return false;
    } else {
      // authorised so return true
      return true;
    }

    // not logged in so redirect to login page
    this.router.navigate(['auth/login']);
    return false;
  }
}

是否要在屏幕上隐藏“编辑”按钮?

模板:

<h1>Some details<h1>
<button *ngIf="canEdit" (click)="enableEditing()>Edit</button>
<p>Details etc etc...</P>

Ts:

export class SomeComponent {
  private readonly editors: Role[] = [Role.Agent, Role.Administrator];

  constructor(private readonly auth: RoleAuthorisationService) {}

  public get canEdit(): boolean { return this.auth.isAuthorised(this.editors); }
}

编辑:要为锁定事物的更具体问题添加答案,除非用户是“经理或更高级别”,您可以(如上)非常具体地说明可以访问该功能的确切角色,或者可以使用枚举。只要按顺序指定了枚举,就可以进行基本的> = <检查。

export enum Role {
  Admin = 1,
  Manager = 2,
  Support = 3,
  Peon = 4
}

...

return CurrentUser.Role <= Role.Manager;