基于角色的访问控制
OmniCRM中的角色、权限和用户
OmniCRM使用基于角色的访问控制(RBAC):人(用户)被分配一个或多个角色,每个角色是一组权限。权限是访问的最小单位(例如,view_customer,create_inventory)。用户的有效访问是所有分配角色的权限的并集。
目的
RBAC使得:
- 数据保护 --- 用户只能看到和做他们被允许的事情。
- 操作适应性 --- 角色反映工作职能(管理员、支持、财务、客户管理员)。
- 简单管理 --- 通过分配角色授予访问权限;避免逐用户的微观管理。
- 租户隔离 --- “查看自己的...”权限限制可见性,仅限于用户自己的客户/租户数据。

用户、角色和权限如何结合在一起
- 用户 --- 实际登录OmniCRM的人。
- 权限 --- 原子能力(例如,
view_customer,delete_product)。 - 角色 --- 权限的命名集合(例如,Admin,Support,Finance)。
- 分配 --- 用户接收一个或多个角色;权限聚合。

身份验证证明你是谁(JWT、API密钥或白名单IP)。授权(角色/权限)决定你可以做什么。
管理用户
OmniCRM用户管理系统允许管理员创建和管理员工用户(管理员、客户服务代理),查看和修改用户角色,重置密码,管理双因素身份验证,并控制用户访问。
用户类型
客户用户 - 通过自助注册或管理员创建。自动分配“客户”角色。这些用户访问自助服务门户以管理他们的服务、查看使用情况、支付发票等。
员工用户 - 由具有适当权限的管理员创建。可以分配角色如Admin、Support、Finance等。这些用户访问CRM界面以管理客户、配置服务、处理账单等。
管理员用户 - 拥有admin权限的用户。拥有对系统的完全访问,包括用户管理、角色管理和所有受保护的端点。
初始管理员用户由Omnitouch团队在系统部署时创建。
添加新用户(管理员和客户服务代理)
管理员可以通过Web UI或API创建新的员工用户。
通过Web UI
- 导航到用户和角色 - 从管理菜单访问用户管理界面
- 点击“添加用户” - ���开用户创建表单

- 填写用户详细信息:
- 用户名 - 登录的唯一用户名(必填)
- 电子邮件 - 用户的电子邮件地址(必填,必须唯一)
- 密码 - 临时密码(必填,用户应在首次登录时更改)
- 名 - 用户的名(必填)
- 中间名 - 用户的中间名(可选)
- 姓 - 用户的姓(必填)
- 电话号码 - 联系电话(可选)
- 角色 - 选择一个或多个要分配的角色(必填)
- 客户联系人 - 可选地将用户链接到客户联系人记录(针对客户用户)
- 点击“创建用户” - 用户被创建并可以立即使用提供的凭据登录
- 用户收到通知 - 可选择发送欢迎电子邮件,包含登录说明
最佳实践:
- 使用像
TempP@ssw0rd!这样的临时密码,并要求用户在首次登录时更改 - 根据工作职能分配适当的角色(见下文的典型角色设计)
- 为所有管理员和支持人员启用双因素身份验证
- 将客户用户链接到他们的客户联系人记录,以便正确的数据范围
通过API
以编程方式创建用户:
端点: POST /auth/users
所需权限: admin
请求体:
{
"username": "john.smith",
"email": "john.smith@company.com",
"password": "TempP@ssw0rd!",
"first_name": "John",
"middle_name": "D",
"last_name": "Smith",
"phone_number": "+61412345678",
"role": "Support"
}
响应:
{
"id": 123,
"username": "john.smith",
"email": "john.smith@company.com",
"first_name": "John",
"last_name": "Smith",
"roles": ["Support"],
"created": "2025-01-04T10:30:00Z"
}
分配多个角色:
用户可以拥有多个角色。权限是累加的(所有分配角色权限的并集)。
要分配多个角色,请在请求中包含它们:
{
"username": "jane.doe",
"email": "jane.doe@company.com",
"password": "TempP@ssw0rd!",
"first_name": "Jane",
"last_name": "Doe",
"role": "Support,Finance"
}
或者在用户创建后使用角色分配端点:
POST /auth/roles/{role_id}/users/{user_id}
查看和搜索用户
列出所有用户(管理员):
GET /auth/users
返回所有用户的分页列表,包括他们的角色和基本信息。
搜索用户:
GET /auth/users/search?search={query}&filters={"role":["Support"]}&page=1&per_page=50
按以下条件过滤:
- 角色名称
- 电子邮件域
- 活跃/已删除状态
- 2FA启用状态
- 最后登录日期
获取特定用户:
GET /auth/users/{user_id}
返回完整的用户详细信息,包括:
- 个人信息
- 分配的角色和有效权限
- 2FA状态
- 最后登录和会话信息
- 关联的客户联系人(如适用)
创建和管理角色
角色是可以分配给用户的权限集合。与其单独将权限分配给每个用户,不如创建将相关权限捆绑在一起的角色,并将这些角色分配给用户。
创建新角色
通过Web UI:
- 导航到用户和角色 → 角色选项卡
- 点击**“创建角色”**
- 输入角色详细信息:
- 名称 - 简短的描述性名称(例如,“Tier2_Support”)
- 描述 - 解释角色的目的和职责
- 点击**“创建”**
- 角色被创建时没有权限;在下一步中添加权限
通过API:
端点: POST /auth/roles
所需权限: admin
请求:
{
"name": "Tier2_Support",
"description": "Level 2 support team with elevated provisioning access"
}
响应:
{
"id": 45,
"name": "Tier2_Support",
"description": "Level 2 support team with elevated provisioning access",
"permissions": [],
"users": []
}
向角色添加权限
一旦角色被创建,分配权限以定义具有该角色的用户可以做什么。
通过Web UI:
- 导航到用户和角色 → 角色选项卡
- 点击角色名称以查看详细信息
- 在权限部分,点击**“添加权限”**
- 从列表中选择一个或多个权限
- 点击**“添加”** - 权限立即被分配


通过API:
端点: POST /auth/roles/{role_id}/permissions
请求:
{
"permission_id": 123
}
或者添加多个权限:
{
"permission_ids": [123, 124, 125]
}
示例:创建“配置专员”角色
该角色可以查看客户、管理服务和配置:
-
创建角色:
POST /auth/roles
{
"name": "Provisioning_Specialist",
"description": "Can provision services and manage customer services"
} -
添加权限:
POST /auth/roles/45/permissions
{
"permission_ids": [
1, # view_customer
20, # view_customer_service
21, # create_customer_service
22, # update_customer_service
30, # view_provision
31, # create_provision
40, # view_inventory
50, # view_product
]
}
从角色中移除权限
通过Web UI:
- 导航到角色详细信息
- 在权限列表中,点击权限旁边的**“X”或“移除”**按钮
- 确认移除
通过API:
端点: DELETE /auth/roles/{role_id}/permissions/{permission_id}
示例:
DELETE /auth/roles/45/permissions/31
这将从角色中移除create_provision权限。
编辑角色详细信息
更新角色名称或描述:
通过Web UI:
- 导航到用户和角色 → 角色选项卡
- 点击要编辑的角色
- 修改角色名称或描述
- 点击**“保存”**

通过API:
端点: PUT /auth/roles/{role_id}
{
"name": "Senior_Support",
"description": "Senior support team with full customer access"
}
删除角色
警告: 删除角色会将其从所有分配的用户中移除。确保用户有替代角色,否则他们将失去访问权限。
通过API:
DELETE /auth/roles/{role_id}
最佳实践: 而不是删除,考虑归档或重命名不再需要的角色。
将角色分配给用户
在用户创建期间:
在用户创建请求中包含角色(见“添加新用户”上文)。
对于现有用户:
通过Web UI:
- 导航到用户和角色 → 用户选项卡
- 点击要编辑的用户
- 在角色部分,选择/取消选择角色
- 点击**“保存”**

通过API:
更新用户的角色:
端点: PUT /auth/users/{user_id}
{
"role": "Support,Finance"
}
或者通过角色端点将单个角色分配给用户:
端点: POST /auth/roles/{role_id}/users/{user_id}
查看角色分配
角色中的所有用户:
GET /auth/roles/{role_id}/users
返回分配给该角色的所有用户的列表。
用户的所有角色:
GET /auth/users/{user_id}
响应包括roles数组,包含所有分配的角色。
管理用户密码
OmniCRM根据上下文提供多种密码管理方法。
用户自助密码重置
忘记密码的用户可以通过登录页面自行重置密码:
- 点击登录页面上的“忘记密码”
- 输入电子邮件地址 - 系统发送密码重置电子邮件
- 检查电子邮件 - 电子邮件包���一个安全的重置链接和令牌(有效期为1小时)
- 点击链接 - 打开密码重置表单
- 输入新密码 - 必须满足密码复杂性要求:
- 至少8个字符
- 至少一个大写字母
- 至少一个小写字母
- 至少一个数字
- 至少一个特殊字符
- 提交 - 密码立即更新;用户可以使用新密码登录
API流程:
-
请求重置:
端点:
POST /auth/forgot_password{
"email": "user@example.com"
}系统生成重置令牌并发送电子邮件。
-
使用令牌重置:
端点:
POST /auth/reset_password{
"token": "abc123...",
"new_password": "NewSecureP@ssw0rd!"
}
管理员密码重置
管理员可以重置用户的密码,而无需电子邮件验证。这会设置一个临时密码,用户应在下次登录时更改。
通过Web UI:
- 导航到用户和角色 → 用户
- 找到用户并点击**“重置密码”**按钮
- 输入临时密码
- 点击**“重置”**
- 通知用户他们的临时密码(通过安全渠道)
- 用户应在下次登录时更改密码
通过API:
端点: POST /auth/users/{user_id}/admin_reset_password
所需权限: admin
请求:
{
"new_password": "TempP@ssw0rd!",
"force_change": true
}
参数:
new_password- 要设置的临时密码force_change(可选) - 如果为true,用户必须在下次登录时更改密码
用户更改自己的密码
经过身份验证的用户可以从其个人资料中更改自己的密码:
端点: POST /auth/change_password
请求:
{
"current_password": "OldP@ssw0rd!",
"new_password": "NewSecureP@ssw0rd!"
}
系统在允许更改之前验证当前密码。
密码安全
- 密码使用bcrypt(werkzeug安全性)进行哈希处理
- 从不以明文存储
- 重置令牌在1小时后过期
- 登录失败尝试可能触发账户锁定(可配置)
- 密码历史跟踪防止重用(可配置)
- 强制执行复杂性要求
管理双因素身份验证(2FA)
OmniCRM支持基于TOTP的双因素身份验证,以增强安全性。管理员可以为用户启用、禁用和重置2FA。

为用户启用2FA
通过Web UI:
- 导航到用户和角色 → 用户
- 点击用户以查看详细信息
- 在安全性��分,点击**“启用2FA”**
- 系统生成:
- TOTP密钥(显示QR码)
- 10个备份代码(一次性使用)
- 用户使用身份验证器应用程序(Google Authenticator、Authy等)扫描QR码
- 用户输入应用程序中的验证码以确认设置
- 用户将备份代码保存在安全位置
- 2FA现在已启用;所有未来的登录都需要

通过API:
-
生成TOTP密钥:
端点:
POST /2fa/enable/user/{user_id}响应:
{
"totp_secret": "JBSWY3DPEHPK3PXP",
"qr_code_url": "otpauth://totp/OmniCRM:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=OmniCRM",
"backup_codes": [
"12345678",
"23456789",
"34567890",
...
]
} -
验证设置:
端点:
POST /2fa/verify-setup/user/{user_id}{
"code": "123456"
}成功时返回
{"verified": true}。
2FA登录流程
一旦启用2FA,登录过程将发生变化:
- 用户输入用户名和密码
- 系统验证凭据
- 如果有效,提示输入2FA代码
- 用户输入来自身份验证器应用程序的代码或备份代码
- 系统验证��码
- 成功后,用户登录

备份代码:
- 在2FA设置期间生成的10个代码
- 仅一次性使用(使用后消耗)
- 如果身份验证器应用程序不可用,则使用
- 用户或管理员可以重新生成
验证2FA代码
端点: POST /2fa/verify/user/{user_id}
{
"code": "123456"
}
接受以下两种:
- TOTP代码(来自身份验证器应用程序的6位数字)
- 备份代码(来自备份代码列表的8位数字)
重新生成备份代码
如果用户耗尽了备份代码或丢失了它们,可以生成新的:
通过Web UI:
- 导航到用户详细信息
- 点击**“重新生成备份代码”**
- 显示或发送新代码给用户
- 旧代码失效
通过API:
端点: POST /2fa/backup-codes/regenerate/user/{user_id}
响应:
{
"backup_codes": [
"98765432",
"87654321",
"76543210",
...
]
}
管理员2FA重置
如果用户失去对其身份验证器应用程序和所有备份代码的访问权限,管理员可以禁用并重新启用2FA。
通过Web UI:
- 导航到用户和角色 → 用户
- 点击用户
- 点击**“重置2FA”**按钮
- 确认重置
- 2FA被禁用;用户可以仅使用密码登录
- 指导用户使用新密钥重新设置2FA
通过API:
端点: POST /2fa/admin/disable/user/{user_id}
所需权限: admin
这将完全禁用用户的2FA:
- 清除TOTP密钥
- 清除备份代码
- 将
is_2fa_enabled标志设置为false
用户可以重新启用2FA以获取新密钥和备份代码。
用户自助2FA重置(新设备)
如果用户获得新设备但仍然可以访问备份代码:
端点: POST /2fa/reset-for-new-device/user/{user_id}
{
"backup_code": "12345678"
}
系统验证备份代码,然后生成新的TOTP密钥和备份代码。用户可以在新设备上设置身份验证器应用程序。
2FA最佳实践
- 要求所有管理员和支持人员启用2FA
- 安全存储备份代码(密码管理器或安全笔记)
- 在使用多个后重新生成备份代码
- 使用信誉良好的身份验证器应用程序(Google Authenticator、Authy、Microsoft Authenticator)
- 记录2FA重置程序供支持人员使用
- 审计2FA使用情况 - 监控哪些用户启用了2FA
更新用户信息
管理员可以随时更新用户详细信息��
通过Web UI:
- 导航到用户和角色 → 用户
- 点击要编辑的用户
- 修改任何可编辑字段:
- 名、名、姓
- 电子邮件地址(需要验证)
- 电话号码
- 角色
- 客户联系人链接
- 点击**“保存”**
通过API:
端点: PUT /auth/users/{user_id}
{
"first_name": "Jane",
"last_name": "Doe-Smith",
"email": "jane.doesmith@newcompany.com",
"phone_number": "+61498765432",
"role": "Support,Finance"
}
电子邮件更改:
当电子邮件被更改时,新电子邮件会被标记为待处理,直到验证:
pending_email字段存储新电子邮件- 向新地址发送验证电子邮件
- 用户点击链接进行验证
email字段更新为新值email_verified标志设置为true
删除用户
OmniCRM对用户使用软删除 - 它们被标记为已删除,但不会从数据库中移除。这保留了审计记录和历史数据。
删除用户
通过Web UI:
- 导航到用户和角色 → 用户
- 找到要删除的用户
- 点击**“删除”**按钮
- 确认删除
- 用户立即被登出,无法再次登录
通过API:
端点: DELETE /auth/users/{user_id}
所需权限: admin
发生了什么:
- 将
deleted标志设置为True - 记录
deleted_at时间戳 - 用户无法登录
- 所有活动会话失效
- 用户仍然出现在审计日志和历史记录中
- 关联数据(客户联系人、活动)被保留
查看已删除用户
过滤已删除用户:
GET /auth/users/search?filters={"deleted":[true]}
恢复已删除用户
如果用户被错误删除,管理员可以恢复他们:
端点: PUT /auth/users/{user_id}
{
"deleted": false
}
这将清除deleted标志,并允许用户再次登录。
注意: 用户的密码保持不变,因此他们可以使用之前的密码。
永久删除用户
警告: 这是不可逆的,并会从数据库中删除所有用户数据。
未通过UI公开。仅通过直接数据库访问可用,以满足合规要求(例如,GDPR数据删除请求)。
用户删除的最佳实践
- 默认软删除 - 保留审计记录
- 记录删除原因 - 在删除之前在活动日志中添加注释
- 转移所有权 - 在删除之前重新分配用户的开放工单、任务
- 审查访问 - 确保没有关键流程依赖于该用户
- 归档数据 - 如有需要,导出用户的工作历史
- ���知相关团队 - 通知经理/同事删除情况
权限目录
权限通常遵循CRUD模式:
view\_*--- 读取/浏览create\_*--- 创建/添加update\_*--- 编辑/修改delete\_*--- 删除/移除
某些实体还包括**“查看自己的...”**变体,限制可见性仅限于当前用户的客户/租户。

全局/管理
admin--- 完全管理访问(管理用户、角色和权限;访问所有受保护的端点)。can_impersonate--- 临时充当其他用户(经过审计;用于支持/故障排除)。
客户及相关记录
- 客户
view_customer,create_customer,update_customer,delete_customer- 自有范围: 查看自己的客户
- 客户网站
view_customer_site,create_customer_site,update_customer_site,delete_customer_site- 自有范围: 查看自己的客户网站
- 客户联系人
view_customer_contact,create_customer_contact,update_customer_contact,delete_customer_contact- 自有范围: 查看自己的客户联系人
- 客户属性(见
客户属性)
view_customer_attribute,create_customer_attribute,update_customer_attribute,delete_customer_attribute- 自有范围: 查看自己的客户属性
- 客户标签(见
客户标签)
view_customer_tag,create_customer_tag,update_customer_tag,delete_customer_tag- 自有范围: 查看自己的客户标签
- 客户服务
view_customer_service,create_customer_service,update_customer_service,delete_customer_service- 自有范围: 查看自己的客户服务
- 客户活动
view_customer_activity,create_customer_activity,update_customer_activity,delete_customer_activity- 自有范围: 查看自己的客户活动
账单
- Stripe卡
view_customer_stripe_card,create_customer_stripe_card,update_customer_stripe_card,delete_customer_stripe_card- 自有范围: 查看自己的客户Stripe卡
- 交易
view_customer_transaction,create_customer_transaction,update_customer_transaction,delete_customer_transaction- 自有范围�� 查看自己的客户交易
- 发票
view_customer_invoice,create_customer_invoice,update_customer_invoice,delete_customer_invoice- 自有范围: 查看自己的客户发票
通信
view_communication,create_communication,update_communication,delete_communication- 自有范围: 查看自己的通信
库存和模板
- 库存
view_inventory,create_inventory,update_inventory,delete_inventory- 自有范围: 查看自己的库存
- 库存模板
view_inventory_template,create_inventory_template,update_inventory_template,delete_inventory_template- 自有范围: 查看自己的库存模板
产品
view_product,create_product,update_product,delete_product
单元广播(CBC)
view_cbc_message,create_cbc_message,update_cbc_message,delete_cbc_message
配置
- 配置
view_provision,create_provision,update_provision,delete_provision- 自有范围: 查看自己的配置
- 配置事件
view_provision_event,create_provision_event,update_provision_event,delete_provision_event
“查看自己的”访问
“查看自己的...”权限将读取(并在实现的情况下可选地编辑)范围限制为与用户自己的客户/租户相关的数据。例如,客户管理员角色可以管理他们租户的联系人、网站、发票和服务,但无法查看其他租户。
典型角色设计
角色 典型权限 备注
系统管理员 admin,可选can_impersonate;以及根据需要的广泛CRUD 对用户/角色/权限的完全控制
支持 view_customer,view_customer_service,view_communication,view_provision;可选更新 如果允许,添加can_impersonate
财务 view_customer_invoice,view_customer_transaction,view_product;可选create_customer_invoice 以读取为主;写入有限
客户管理员(租户) “查看自己的...”跨客户、���站、联系人、服务、库存、发票、交易、通信、配置 租户范围管理
只读审计员 仅广泛的view_* 无创建/更新/删除
: 示例角色和包含的权限(摘要)
通过API管理角色和权限
所有端点都需要admin权限。
列出权限
端点: GET /auth/permissions
创建权限(少见)
端点: POST /auth/permissions
请求体:
{
"name": "view_example",
"description": "Read-only access to example objects"
}
列出角色
端点: GET /auth/roles
创建角色
端点: POST /auth/roles
请求体:
{
"name": "Support",
"description": "Tier-1 support team"
}
向角色添加权限
端点: POST /auth/roles/{role_id}/permissions
请求体:
{
"permission_id": 123
}
从角色中移除权限
端点: DELETE /auth/roles/{role_id}/permissions/{permission_id}
将角色分配给用户
创建具有角色的用户
端点: POST /auth/users
请求体:
{
"username": "sara",
"email": "sara@example.com",
"password": "TempP@ssw0rd!",
"first_name": "Sara",
"last_name": "Ng",
"phone_number": "+61...",
"role": "Support"
}
更新用户的角色
端点: PUT /auth/users/{user_id}
请求体:
{
"role": "Finance"
}
列出用户(仅管理员)
端点: GET /auth/users
伪装(受控)
- 要求:
can_impersonate或admin
开始伪装
端点: POST /auth/impersonate
请求体:
{ "user_id": 42 }
停止伪装
端点: POST /auth/stop_impersonation
最佳实践
- 优先考虑最小权限。 从最小角色开始;根据需要添加权限。
- 优先使用“查看自己的...”。 对于面向客户的角色,使用租户范围的权限。
- 保持角色稳定。 当功能发生变化时更新角色权限——不要编辑每个用户。
- 定期审计。 审查谁拥有
admin或can_impersonate。
常见问题
用户可以拥有多个角色吗? 是的。权限是累加的。
我需要自定义权限吗? 通常不需要。内置目录覆盖大多数需求。
“查看自己的...”规则如何知道什么是我的? 它们评估用户/联系人与客户(租户)之间的链接。