在前幾篇,我們談了路由跟狀態管理,有了這些概念之後,就能處理下一個問題:
👉 誰,能對什麼資料,做什麼操作?
業界常見的二分法是「RBAC = 粗、ABAC = 細」,但實務上我們更常遇到三個層次:
權限層次 | 常見模式 | 前端應用 (Angular 17 + ng-zorro) | 後端備註 | 原理說明 |
---|---|---|---|---|
粗粒度 (角色導向) | RBAC | - 依角色顯示或隱藏功能- Router 守衛判斷角色 | 後端仍需驗證角色 | 基於角色,設計簡單,彈性不足 |
中粒度 (資源導向) | Resource-Based(常見實作為 RBAC + Resource-Based) | - 功能點 / API 權限檢查- Router 模組級守衛 | 後端需比對資源與操作 | 基於資源/操作,比 RBAC 更細 |
細粒度 (屬性/規則導向) | ABAC / PBAC | - 按鈕依資料屬性動態判斷- Table 行級限制 | 後端需檢查屬性 / 資料條件 | 基於「使用者 × 資料 × 環境」條件,最精細 |
前端:Angular Router 守衛
canActivate(): boolean {
return this.auth.hasRole('Admin');
}
前端:UI 控制 (ng-zorro 按鈕)
<button nz-button *ngIf="auth.hasRole('Admin')">管理後台</button>
常見上是 RBAC + Resource-Based 實作
前端:功能按鈕權限檢查
<button nz-button *ngIf="auth.hasPermission('order.edit')">編輯訂單</button>
Router:模組級守衛
{
path: 'orders',
component: OrdersComponent,
canActivate: [PermissionGuard],
data: { requiredPermission: 'order.view' }
}
前端:按鈕依資料屬性動態判斷
<button nz-button [disabled]="!auth.canEdit(order)">編輯</button>
canEdit(order: Order): boolean {
return order.ownerId === this.auth.currentUser.id;
}
Table:Row 層級控制
<tr *ngFor="let order of orders"
[class.disabled]="!auth.canView(order)">
<td>{{ order.id }}</td>
<td>{{ order.owner }}</td>
</tr>
👉 權限管理不只是安全議題,更是架構可維護性的關鍵。