【问题标题】:How to prevent actions by user role in Angular如何防止 Angular 中用户角色的操作
【发布时间】:2019-08-07 17:17:31
【问题描述】:

我已经有一个 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 一个按钮)

【问题讨论】:

  • 您实际上可以做得更好,而不是让它们出现在路线数据中。我建议您创建一个 ngrx-state/ service 来存储这些信息,然后基于组件中的该状态/一个通用服务包装用于编辑的逻辑,并在路由 gaurd 中重用这些逻辑

标签: angular security angular-guards


【解决方案1】:

将您的授权代码分解为您的警卫和其他服务都可以使用的服务(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); }
}

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

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

...

return CurrentUser.Role <= Role.Manager;

【讨论】:

猜你喜欢
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多