首页
/ 5分钟上手Directus多租户权限:从混乱到精细化的用户管理方案

5分钟上手Directus多租户权限:从混乱到精细化的用户管理方案

2026-02-04 04:32:02作者:房伟宁

你是否正在为多租户系统的权限管理头疼?不同客户数据隔离、角色权限交叉、实时同步冲突——这些问题让许多开发者在权限设计上耗费数月。本文将通过Directus的用户管理模块,带你实现从0到1的多租户权限架构,3步解决数据隔离与权限分配难题。读完你将掌握:多租户权限模型设计、角色继承配置、实时权限同步实现。

Directus权限系统核心架构

Directus通过三层权限模型实现精细化控制:全局权限(Global Access)、集合权限(Collection Permissions)和字段权限(Field Permissions)。这种分层结构在api/src/permissions/modules/fetch-global-access/fetch-global-access.ts中通过fetchGlobalAccess函数实现,该函数组合用户与角色权限,采用"或"逻辑处理权限叠加:

// 权限合并核心逻辑
access.app ||= userAccess.app;  // 用户权限覆盖角色权限
access.admin ||= userAccess.admin;

权限架构分层

权限架构分层示意图:全局权限(蓝色)、集合权限(绿色)、字段权限(橙色)

多租户权限设计三要素

1. 租户数据隔离实现

Directus通过集合前缀过滤器权限实现租户隔离。在packages/system-data/src/fields/permissions.yaml中定义的tenant_id字段是关键,通过在权限规则中添加:

{
  "filter": {
    "tenant_id": { "_eq": "$CURRENT_TENANT_ID" }
  }
}

系统会自动为每个查询附加租户条件。这种设计在api/src/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.ts中通过角色过滤实现:

const query = knex.where('role', 'in', accountability.roles);

2. 角色继承体系

Directus支持角色的层级继承,管理员可创建"租户管理员"、"租户用户"等模板角色。角色定义位于packages/system-data/src/fields/roles.yaml,核心继承逻辑在权限合并时自动生效:

// 角色权限缓存键生成
({ roles, ip }) => ({ roles, ip }),

通过缓存机制提升权限计算性能,确保多租户场景下的系统响应速度。

3. 实时权限同步

权限变更后,Directus通过WebSocket实时推送更新,实现多实例权限同步。相关实现位于api/src/websocket/index.ts,配合api/src/emitter.ts的事件机制,确保权限修改秒级生效。

实战:配置多租户权限三步法

步骤1:创建租户隔离集合

在Directus数据模型中添加租户标识字段:

  1. 进入设置 > 数据模型
  2. 为所有租户共享集合添加tenant_id字段(UUID类型)
  3. packages/system-data/src/fields/index.ts中注册字段定义:
processFields(permissionFields);  // 处理权限字段定义

步骤2:配置角色模板

创建三级角色体系:

  • 系统管理员:全权限,无租户限制
  • 租户管理员:管理本租户用户,无跨租户权限
  • 租户用户:仅访问授权数据

角色创建界面调用app/src/views/settings/roles/role-form.vue组件,权限配置存储在packages/system-data/src/app-access-permissions/app-access-permissions.yaml

步骤3:实现权限过滤器

在权限规则中添加租户过滤:

  1. 进入设置 > 角色 > 编辑权限
  2. 添加条件{ "tenant_id": { "_eq": "{{ $current_user.tenant_id }}" }}
  3. 系统自动在api/src/permissions/modules/process-ast/process-ast.test.ts中验证权限表达式:
test('Validates all paths in AST and throws if no permissions match', async () => {
  const accountability = { user: null, roles: [] } as unknown as Accountability;
  // ...验证逻辑
});

常见问题与解决方案

权限冲突排查

当出现权限不生效时,可检查:

性能优化建议

在租户数量超过100时,建议:

  1. 启用权限缓存(默认开启,缓存键定义在api/src/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.ts
  2. 定期清理权限日志(api/src/services/activity.ts
  3. tenant_id字段建立索引

总结与进阶

通过Directus的权限系统,我们实现了多租户环境下的数据安全隔离与灵活授权。核心优势在于:

  • 无需代码:通过界面配置实现复杂权限逻辑
  • 实时生效:权限变更秒级同步到所有实例
  • 扩展灵活:支持自定义权限验证器

进阶学习建议:

Directus权限管理界面

Directus权限管理界面:可视化配置多租户权限规则

立即访问README.md开始你的多租户权限之旅,或查看app/src/views/settings/roles/index.vue的角色管理界面源码,深入了解前端实现细节。

登录后查看全文
热门项目推荐
相关项目推荐