首页 > 解决方案 > 如何防止 Angular 中用户角色的操作

问题描述

我已经有一个 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: [
        { ... 

需要修复这两个主题:

data: { roles: [] }1)我只想通过较低级别的线路(如代理);

2)内部组件告诉只有经理可以编辑数据(disable如果角色==支持或代理,则只有一个按钮)

标签: angularsecurityangular-guards

解决方案


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

推荐阅读