Skip to content

别名配置

在 Yao 引擎的 ACL(访问控制列表)设计架构中,features/alias.ymlscopes/alias.yml 虽然都使用了“别名(Alias)”这一概念来进行分组管理,但它们分别作用于完全不同的应用层级:前端表现层后端数据层

简单来说:features 决定用户能“看见”什么,而 scopes 决定用户能“执行”什么。

以下是详细的对比分析:

1. features/alias.yml (前端特性组)

这个文件位于 openapi/features/alias.yml,它属于 Feature Flag(特性开关) 系统的一部分。

  • 核心作用UI 组件的可见性控制。 它将多个原子特性(Feature)打包成一个更易管理的组。这些配置最终会通过 API 返回给前端,前端根据这些标记来决定是否渲染某个菜单、按钮或页面区块。
  • 配置对象:针对的是“功能点”或“界面元素”。
  • 安全性。这只是一种展示逻辑。如果后端没有对应的保护,用户可以通过直接调用 API 绕过前端限制。

配置示例分析

yaml
# 定义一个名为 profile:manage 的别名
profile:manage:
  - profile:read # 原子特性:查看个人资料页
  - profile:edit # 原子特性:显示编辑按钮

# 定义一个更高级的别名 user:full,包含上述别名
user:full:
  - profile:manage # 嵌套引用
  - team:manage

实际应用场景: 前端调用 /api/v1/features 获取当前用户的特性列表。如果返回了 profile:edit,前端 React/Vue 组件就会渲染“编辑”按钮;否则该按钮隐藏。


2. scopes/alias.yml (后端权限组)

这个文件位于 openapi/scopes/alias.yml,它属于 OAuth2 / RBAC(基于角色的访问控制) 系统的一部分。

  • 核心作用API 端点的数据安全与访问控制。 它将多个原子权限(Scope)打包成一个组。这些配置被后端 ScopeManager 加载,用于在请求到达 API 处理器之前进行拦截和校验。
  • 配置对象:针对的是“API 资源”和“HTTP 动作”(如 GET, POST)。
  • 安全性。这是系统的最后一道防线。无论前端是否显示了按钮,只要请求不包含正确的 Scope,后端都会拒绝执行并返回 403 Forbidden

配置示例分析

yaml
# 定义名为 kb:own 的权限组,允许操作自己的知识库
kb:own:
  - collections:read:own # 允许 GET /kb/collections/own
  - collections:write:own # 允许 POST /kb/collections/own
  - documents:read:own

# 系统管理员权限,使用通配符
system:root:
  - '*:*:*'

实际应用场景: 当用户发起 POST /kb/collections 请求时,Yao 引擎的中间件(Middleware)会检查该用户的角色是否拥有 collections:write 相关的 Scope。如果没有,请求会被立即拦截。


3. 核心差异对比表

维度features/alias.ymlscopes/alias.yml
作用域前端 (Frontend)后端 (Backend)
控制对象UI 界面、菜单、按钮API 接口、数据库读写
验证逻辑if (features["profile:edit"])acl.Enforce(c) (中间件自动执行)
失败后果用户看不到按钮 (UI 隐藏)请求报错 403 Forbidden (访问拒绝)
数据约束不涉及数据过滤支持 owner: true 等数据行级过滤
主要目的用户体验 (UX)、功能分级数据安全 (Security)、防御

4. 为什么需要两套配置?(最佳实践)

Yao 采用这种分离设计是为了实现最大程度的灵活性和解耦

  1. 灰度发布/功能开关:你可能已经开发好了后端的 API (Scope 已配置),但希望只对 10% 的用户开放入口。此时,你只需要在 features 中限制该功能,而无需修改后端安全策略。
  2. 多端适配:移动端和 Web 端可能共用一套后端 API (Scopes 相同),但界面功能完全不同 (Features 不同)。
  3. 细粒度控制
    • Feature: team:view (只控制是否能看到团队菜单)。
    • Scope: team:read:basic (只读基础信息), team:read:sensitive (读取敏感薪资信息)。
    • 这种分离允许前端只有一个入口,但后端根据权限返回不同详细程度的数据。

总结

  • 修改 features/alias.yml 是为了告诉前端:“这群人能看到这些菜单”。
  • 修改 scopes/alias.yml 是为了告诉后端:“这群人能调用这些接口”。

在实际开发中,当你添加一个新模块时,通常需要在 scopes 中定义它的 API 安全规则,同时在 features 中定义它的 UI 入口,并在各自的 alias.yml 中进行分组,最后分配给 Role。