本介绍了 Dify 的帐户和租户管理系统,该系统负责处理平台内的用户身份验证、工作区(租户)管理和用户权限。提供了全面的用户身份管理、多工作区支持以及基于角色的访问控制。
系统概述
帐户和租户管理系统是 Dify 的核心组件,用于管理:
- 用户帐户(User Accounts) ——注册、身份验证、配置文件管理
- 工作区(租户) - 拥有自己的成员和资源的组织单位
- 成员资格和角色 - 工作区内基于角色的访问控制
- 身份验证流程 - 多种身份验证方法,包括密码、电子邮件代码和 OAuth
架构图
数据模型
该系统围绕以下主要实体构建:
帐户管理
帐户创建和注册
Dify 支持多种创建账户的路径:
- 标准注册 - 电子邮件/密码注册
- 基于 OAuth 的注册 - 通过 GitHub 或 Google 注册
- 基于邀请的注册 - 受邀加入工作区
- 初始设置 - 系统设置期间的第一个用户
帐户创建主要由 AccountService
和 RegisterService
类处理。create_account
处理核心帐户创建逻辑,包括密码哈希和默认设置。
身份验证方法
Dify 支持多种身份验证方法:
- 基于密码的登录 - 传统的用户名/密码
- 电子邮件代码登录 - 一次性代码发送至电子邮件
- OAuth 提供商 - GitHub 和 Google 集成
- 基于令牌的身份验证 - 用于 API 访问的 JWT 令牌
身份验证由 AccountService
类管理,每种身份验证方法都有专门的方法:
密码验证:
account = AccountService.authenticate(email, password)
token_pair = AccountService.login(account=account, ip_address=ip_address)
JWT 令牌管理:
access_token = AccountService.get_account_jwt_token(account)
refresh_token = _generate_refresh_token() AccountService._store_refresh_token(refresh_token, account.id)
帐户安全功能
该系统实现了多项安全功能:
- 密码哈希 - 使用加盐密码哈希
- 速率限制 ——限制登录尝试和密码重置请求
- 基于 IP 的限制 - 限制通过 IP 发送电子邮件
- 令牌过期 - JWT 令牌在配置的时间后过期
- 刷新令牌轮换 - 刷新时使用新令牌以确保安全
租户(工作区)管理
Dify 中的租户代表包含应用程序、数据集和模型提供程序等资源的工作区。一个用户可以属于多个具有不同角色的租户,但同一时间只能有一个活跃租户。
租户创建
创建租户:
- 创建帐户时自动执行(默认工作区)
- 由具有适当权限的用户手动
TenantService
类负责处理租户的创建和管理:
tenant = TenantService.create_tenant(name)
TenantService.create_tenant_member(tenant, account, role="owner")
创建租户时,它会生成一个 RSA 密钥对以用于安全操作:
tenant.encrypt_public_key = generate_key_pair(tenant.id)
基于角色的访问控制(Role-Based Access Control)
Dify 通过 TenantAccountJoin
表在租户内部实现基于角色的访问控制,该表定义了帐户和租户之间的关系。每个连接都关联一个角色:
- 所有者(Owner) - 完全管理控制
- 管理员(Admin) - 可以管理大多数资源,但不能删除工作区
- 普通用户(Normal) - 具有有限权限的普通用户
- 数据集操作员(Dataset Operator) - 数据集管理的特殊角色
租户切换
用户可以属于多个租户并在它们之间切换。系统会跟踪每个用户的当前活动租户:
TenantService.switch_tenant(account, tenant_id)
当用户登录时,系统会加载其当前租户:
current_tenant = TenantAccountJoin.query.filter_by(account_id=account.id, current=True).first()
if current_tenant:
account.current_tenant_id = current_tenant.tenant_id
成员管理
邀请成员
工作区管理员可以邀请新成员加入租户。邀请流程包括:
- 生成邀请令牌
- 发送带有令牌的电子邮件
- 如果用户不存在则创建待处理帐户
- 接受邀请后分配角色
管理成员角色
工作区管理员可以更新现有成员的角色:
TenantService.update_member_role(tenant, member, new_role, operator)
更改所有者角色时,系统会确保始终只有一个所有者:
if new_role == "owner":
# Find the current owner and change their role to 'admin'
current_owner_join = TenantAccountJoin.query.filter_by(tenant_id=tenant.id, role="owner").first() current_owner_join.role = "admin"
移除成员
工作区管理员可以从租户中删除成员:
TenantService.remove_member_from_tenant(tenant, account, operator)
系统在允许删除成员之前会检查权限:
TenantService.check_member_permission(tenant, operator, account, "remove")
身份验证流程
登录流程
身份验证流程
密码重置流程
安全注意事项
速率限制
系统实施速率限制以防止滥用:
- 登录尝试(Login attempts) - 限制错误密码尝试次数
- 密码重置(Password reset) - 限制密码重置电子邮件
- 邮箱验证码登录(Email code login) - 限制验证码邮箱
- 基于 IP 的限制(IP-based limits) - 通过 IP 地址限制电子邮件发送
reset_password_rate_limiter = RateLimiter(prefix="reset_password_rate_limit", max_attempts=1, time_window=60 * 1)
email_code_login_rate_limiter = RateLimiter(prefix="email_code_login_rate_limit", max_attempts=1, time_window=60 * 1)
LOGIN_MAX_ERROR_LIMITS = 5 FORGOT_PASSWORD_MAX_ERROR_LIMITS = 5
Token 管理
系统使用两种类型的令牌:
- 访问令牌(Access tokens) - 用于 API 身份验证的短期 JWT 令牌
- 刷新令牌(Refresh tokens) - 存储在 Redis 中的长期令牌,用于获取新的访问令牌
REFRESH_TOKEN_PREFIX = "refresh_token:"
ACCOUNT_REFRESH_TOKEN_PREFIX = "account_refresh_token:"
REFRESH_TOKEN_EXPIRY = timedelta(days=dify_config.REFRESH_TOKEN_EXPIRE_DAYS)
删除帐户
Dify 支持通过验证流程删除帐户:
- 用户请求删除帐户
- 系统通过电子邮件发送验证码
- 用户通过验证码确认
- 帐户正在等待删除
# Generate verification
code code = "".join([str(random.randint(0, 9)) for _ in range(6)])
token = TokenManager.generate_token(account=account, token_type="account_deletion", additional_data={"code": code})
# Delete account
delete_account_task.delay(account.id)
与其他系统集成
帐户和租户管理系统与 Dify 的其他各种组件集成:
- 模型提供者系统(Model Provider System) - 使用租户上下文进行 API 密钥管理
- RAG 知识系统(RAG Knowledge System) - 根据租户成员资格控制对数据集的访问
- 对话系统(Conversation System) - 将对话与用户和租户关联起来
- 工作流系统(Workflow System) - 根据租户角色强制执行权限
总结
详细介绍了 Dify 的帐户和租户管理系统,该系统负责处理平台内的用户身份验证、工作区(租户)管理和用户权限。提供了全面的用户身份管理、多工作区支持以及基于角色的访问控制。
同时确保与其他系统集成时,Dify 内的所有资源都由租户正确隔离,并且在整个应用程序中实施适当的访问控制。
接下来将分别介绍各个子系统:
模型提供者系统(Model Provider System)
RAG 知识系统(RAG Knowledge System)
对话系统(Conversation System)
工作流系统(Workflow System)
推荐阅读
- 从零开始学 Dify-系统架构
- 从零开始学 Dify- API 后端架构原来是这样设计的
- A2A 与 MCP 协议的深度融合:智能体生态的互补性与协同
- 手把手实操!我用扣子搭建了一个漫画生成的Agent
- 最简单的方式把 AI Agent 讲明白、用明白 - 来自著名 Agent 框架 Agno 创始人的优质分享
- 大模型应用开发从小工到专家
- AI Agent 视觉指南:通过 60 张可视化图表透视智能体
- 全面剖析 MCP、A2A 与 Function Calling 的架构关系
参考资料
https://github.com/langgenius/dify
欢迎关注公众号,更及时的接收消息,后续会继续写一些相关 LLM 的文章。