@casl/angular

中文文档
10.2.0发布于 2026/10/30MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 6.7万

CASL 的角模块, 这使得在任意角应用程序中添加权限变得容易

中文使用文档
文档目录11 节
  1. 安装
  2. 配置应用程序
  3. 更新能力实例
  4. 使用 AbilityService 在模板中检查权限
  5. 信号支持
  6. 解释权限检查 whyCan 财务报告和审定财务报表 whyCannot
  7. 创建权限信号 defer* 方法
  8. 使用管道检查模板中的权限( 已过期)
  9. 类型脚本支持
  10. 想帮忙吗?
  11. 许可证

化学文摘社

@casl/angular NPM version Support

此软件包允许集成 @casl/ability 与 角质 应用。 它提供腐烂的 AblePipe, (中文(简体) ), AblePurePipe 新建 AbilityService 财务报告和审定财务报表 AbilityServiceSignal 转到Angular模板,这样就可以根据用户查看它们的能力显示或隐藏组件,按钮等.

安装

npm install @casl/angular @casl/ability
# or
yarn add @casl/angular @casl/ability
# or
pnpm add @casl/angular @casl/ability

配置应用程序

要将管道添加到应用程序的模板中, 您需要导入所需的管道

import { NgModule } from '@angular/core';
import { AblePipe } from '@casl/angular';
import { createMongoAbility, Ability } from '@casl/ability';

@NgModule({
  imports: [
    // other modules
    AblePipe
  ],
  providers: [
    { provide: Ability, useValue: createMongoAbility() }
  ]
  // other properties
})
export class AppModule {}

读取 CASL 和类型脚本 获取更多细节 MongoAbility 类型配置.

更新能力实例

需要权限检查支持的应用程序大多有类似的东西 AuthService 或者说 LoginService 或者说 Session 服务(按您的意愿命名),负责用户登录/登录功能。 每次用户登录(和登录),我们需要更新 Ability 以新规则为例.

让我们想象一下,服务器返回的用户在登录上有一个角色:

import { Ability, AbilityBuilder } from '@casl/ability';
import { Injectable } from '@angular/core';

@Injectable({ provideIn: 'root' })
export class Session {
  #token: string

  constructor(@Inject(Ability) private ability: MongoAbility) {}

  login(details) {
    const params = { method: 'POST', body: JSON.stringify(details) };
    return fetch('path/to/api/login', params)
      .then(response => response.json())
      .then((session) => {
        this.updateAbility(session.user);
        this.#token = session.token;
      });
  }

  private updateAbility(user) {
    const { can, rules } = new AbilityBuilder(createMongoAbility);

    if (user.role === 'admin') {
      can('manage', 'all');
    } else {
      can('read', 'all');
    }

    this.ability.update(rules);
  }

  logout() {
    this.#token = null;
    this.ability.update([]);
  }
}

见 定义规则 获取更多关于如何定义的信息 Ability。 。 。 .

那就用这个 Session 服务于 LoginComponent数字 :

import { Component } from '@angular/core';
import { Session } from '../services/Session';

@Component({
  selector: 'login-form',
  template: `
    <form (ngSubmit)="login()">
      <input type="email" [(ngModel)]="email" />
      <input type="password" [(ngModel)]="password" />
      <button type="submit">Login</button>
    </form>
  `
})
export class LoginForm {
  email: string;
  password: string;

  constructor(private session: Session) {}

  login() {
    const { email, password } = this;
    return this.session.login({ email, password });
  }
}

使用 AbilityService 在模板中检查权限

AbilityService 是提供 ability$ 可见. DI中提供的可观察到的注射剂 Ability 并每次修改规则时发出。 这样可以高效使用权限检查,特别是在我们使用的情况下 ChangeDetectionStrategy.OnPush。 。 。 .

让我们先看看它如何用于任何组件:

@Component({
  selector: 'my-home',
  template: `
    @if (ability$ | async as ability) {
      <h1>Home Page</h1>
      @if (ability.can('create', 'Post')) {
        <button>Create Post</button>
      }
    }
  `
})
export class HomeComponent {
  readonly ability$: Observable<AppAbility>;

  constructor(abilityService: AbilityService<AppAbility>) {
    this.ability$ = abilityService.ability$;
  }
}

也可以安全地在里面使用 *ngFor 和其他指示。 如果我们用 ChangeDetectionStrategy.OnPush,这将给我们更多的业绩改进,因为 ability.can(...) ⊿τ惠璶碞ぃ穦.

这种方法从绩效角度来说是行之有效的,因为它每个组件只产生单一订阅(而不是每一次核对) ablePure 并且不需要我们的部件使用 Default 或者说 OnPush 战略.

如何使用管道进行许可检查

信号支持

@casl/angular的最新版本也支持新版本 signal在您的应用中使用它,而不是 AbilityService 使用情况 AbilityServiceSignal数字 :

import { AbilityServiceSignal } from '@casl/angular';
import { AppAbility } from './AppAbility';

@Component({
  selector: 'my-home',
  template: `
      <h1>Home Page</h1>
      @if (can('create', 'Post')) {
        <button>Create Post</button>
      }
  `
})
export class HomeComponent {
  private readonly abilityService = inject<AbilityServiceSignal<AppAbility>>(AbilityServiceSignal);
  protected readonly can = this.abilityService.can;
}

解释权限检查 whyCan 财务报告和审定财务报表 whyCannot

AbilityServiceSignal whyCan 财务报告和审定财务报表 whyCannot 方法有助于回答为什么允许或界定行动的问题:

const abilityService = inject<AbilityServiceSignal<AppAbility>>(AbilityServiceSignal);

abilityService.update([
  { action: 'create', subject: 'Post', reason: 'You can create posts' },
  {
    inverted: true,
    action: 'delete',
    subject: 'Post',
    reason: 'Only administrators can delete posts'
  }
]);

abilityService.whyCan('create', 'Post'); // { reason: 'You can create posts' }
abilityService.whyCan('delete', 'Post'); // null
abilityService.whyCannot('delete', 'Post'); // { reason: 'Only administrators can delete posts' }
abilityService.whyCan('update', 'Post'); // null
abilityService.whyCannot('update', 'Post'); // { reason: undefined }
abilityService.whyCannot('create', 'Post'); // null

将这些方法显示为模板,与 can 像这样使用它们:

@if (whyCannot('delete', 'Post'); as forbidden) {
  <span>{{ forbidden.reason || 'You cannot delete posts' }}</span>
} @else {
  <button (click)="deletePost()">Delete Post</button>
}

无故匹配倒置规则返回对象 reason: undefined 当方法的条件得到满足时。 即便没有任何解释,这仍然使否认真相.

创建权限信号 defer* 方法

这个 defer* 方法返回计算出的信号。 每个参数(动作,主题,或可选字段)都可以是一个平面值或信号. 返回的信号在能力规则或任何信号参数发生变化时会重新计算.

一次创建这些信号, 例如在组件字段初始化器中, 在模板中读取 :

import { Component, inject, input } from '@angular/core';
import { AbilityServiceSignal } from '@casl/angular';
import type { AppAbility } from './AppAbility';

@Component({
  selector: 'post-action',
  template: `
    @if (whyCannotPerformAction(); as forbidden) {
      <p>{{ forbidden.reason || 'This action is forbidden' }}</p>
    } @else {
      <button>Perform action</button>
    }
  `
})
export class PostActionComponent {
  private readonly abilityService = inject<AbilityServiceSignal<AppAbility>>(AbilityServiceSignal);
  readonly action = input.required<'create' | 'delete'>();

  protected readonly whyCannotPerformAction = this.abilityService.deferWhyCannot(this.action, 'Post');
}

例如,由父母提供动作 <post-action [action]="'delete'" />。当输入更改时,权限信号更新.

传递信号本身( P)this.action跟踪其变化。 传递其当前值( E)this.action()将这一参数固定在创建延迟检查时的数值上。 这个 deferWhy* 方法保存 null 和缺失的理由行为 why* 方法; 使用 deferCan 或者说 deferCannot 您只需检查布尔权限即可.

使用管道检查模板中的权限( 已过期)

检查您可以使用的任何模板的权限 AblePipe数字 :

@if ('create' | able: 'Post') {
  <a (click)="createPost()">Add Post</a>
}

类型脚本支持

这个软件包是用 TypeScript 写的, 这样可以警告您使用错误 .

在Angular app中使用应用程序特定能力可能有点乏味,因为你到处注射 Ability 您需要导入其通用参数:

import { Ability } from '@casl/ability';
import { Component } from '@angular/core';
import { AppAbilities } from '../services/AppAbility';

@Component({
  selector: 'todo-item'
})
export class TodoItem {
  constructor(
    private ability: Ability<AppAbilities>
  ) {}
}

为了让生活变得容易,你可以使用 AbilityClass<TAbility> 类以使用伴星对象模式:

import { Ability, AbilityClass } from '@casl/ability';

type Actions = 'create' | 'read' | 'update' | 'delete';
type Subjects = 'Article' | 'User';

export type AppAbility = MongoAbility<[Actions, Subjects]>;
export const AppAbility = Ability as AbilityClass<AppAbility>;

使用 AppAbility 在你的应用程序中 :

import { NgModule } from '@angular/core';
import { AppAbility } from './services/AppAbility';

@NgModule({
  // other configuration
  providers: [
    { provide: AppAbility, useValue: createMongoAbility() },
  ]
})
export class AppModule {}

想帮忙吗?

想要提交错误, 提供一些代码, 还是改进文档 ? 不错! 阅读指南 捐款。 。 。 .

如果你想帮助我们 维持我们的社区和项目,考虑 成为开放集体的出资人

见 支助CASL 详情

许可证

MIT 许可证

版本与发布记录

@casl/angular 共发布 68 个版本,首次发布于 2018/03/18;过去 12 个月发布了 8 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
10.2.0latest2026/10/3010 天前
10.1.02026/10/2811 天前
10.0.32026/08/093 个月前
10.0.12026/07/074 个月前
10.0.02026/05/215 个月前
10.0.0-rcnext2026/05/086 个月前

其他发布通道:canary → 0.1.0-alpha.ade5be4a,next → 10.0.0-rc。

关于 @casl/angular 的常见问题

@casl/angular 是什么?

CASL 的角模块, 这使得在任意角应用程序中添加权限变得容易

如何安装 @casl/angular?

在项目目录运行 npm install @casl/angular,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:rxjs(^7.5.5)、tslib(^2.0.0)、@angular/core(^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0)、@casl/ability(^7.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@casl/angular 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@casl/angular 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@casl/angular 可以商用吗?

@casl/angular 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@casl/angular 的下载量有多少?

根据 npm 官方下载统计,@casl/angular 在 2026/10/09 – 2026/11/07 这 30 天内被下载 66,803 次,日均约 2,227 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@casl/angular 还在维护吗?

最新版本 10.2.0 发布于 2026/10/30(10 天前);至今共发布 68 个版本,其中过去 12 个月发布了 8 个;首次发布于 2018/03/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。