通过 USIP 与你的系统集成
概述
其实,Univer 的后端服务没有集成账户系统(也不应该集成),默认配置下,Univer 的后端服务不会对访问者进行身份认证,也即所有用户都可访问所有的资源。
如果你需要对用户进行身份认证,认证通过才能使用,那么你必须实现自己的账户系统。你可以配置 Univer Server 和你的系统进行交互,Univer Server 在需要认证用户身份的时候即会调用你的系统完成认证。
为了实现这类交互,Univer 设计了 Univer Server 集成协议 USIP(Univer Server Integration Protocol)。USIP本质上是一种 SPI(Service Provider Interface
),也即由 Univer 来定义接口,然后由你的系统进行实现。Univer 根据客户的潜在需求,已经定义好了一些 USIP 接口,你可以选择实现一些接口来改变 Univer 处理某些用户请求的流程,比如进行用户认证和权限校验。如果当前已有 USIP 接口无法满足你的需求,可以给我们提出建议。
USIP接口说明
目前 Univer 定义了两类场景的 USIP 接口:
- 账户类
- 身份认证
- 用户信息获取:name、avatar 之类的基础信息
- 权限类
- 获取用户在某一文档上的权限角色
- 获取某一文档的协作者列表
下面介绍各个接口的详细说明
用户身份认证
调用场景
用户每次与 Univer 后端服务进行交互都会调用
交互流程
协议定义
HTTP 方法 | Headers | 传参方式 | 响应数据格式 |
---|---|---|---|
GET | 透传用户传输的所有 header,保障你可以用于身份认证 | 无传参 | application/json |
请求参数
无请求参数
响应数据
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
user | Object | 认证成功时,返回user对象 | |
user.userID | string | ace55655ceabd55 | 用户的 ID,只需确保能和你们的真实用户一一映射即可,建议使用 open_uid |
user.name | string | alice | 用户的名字,用于在前端展示协作者信息 |
user.avatar | string | https://image.xx/acde55acb45bbead55 | 用户的头像 URL,用于在前端展示协作者信息 |
响应示例:
{
"user": {
"userID": "ace55655ceabd55g",
"name": "alice",
"avatar": "https://image.xx/acde55acb45bbead55"
}
}
批量获取用户信息
调用场景
多人协作时,展示当前协作者的头像、名字;查看文档中的评论列表时,展示评论用户的头像、名字
交互流程
协议定义
HTTP 方法 | Headers | 传参方式 | 响应数据格式 |
---|---|---|---|
POST | 无自定义 header,也不会透传用户请求的 header | Body: raw Json | application/json |
请求参数
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
userIDs | array[string] | [“user_id1”, “user_id2”] | 用户 ID 数组 |
请求示例:
{
"userIDs": [ "user_id1", "user_id2", "user_id3" ]
}
响应数据
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
users | array[Object] | 用户对象数组,包含请求中的每一个用户,用户对象的定义已在身份认证接口描述 |
响应示例:
{
"users": [
{"userID": "user_id1", "name":"name1", "avatar":"https://xxxx"},
{"userID": "user_id2", "name":"name2", "avatar":"https://xxxx"},
{"userID": "user_id3", "name":"name3", "avatar":"https://xxxx"}
]
}
用户权限角色获取
调用场景
用户读取 / 编辑文档时,获取其权限角色来判断是否有对应操作的权限
交互流程
协议定义
HTTP 方法 | Headers | 传参方式 | 响应数据格式 |
---|---|---|---|
GET | 无自定义 header,也不会透传用户请求的 header | Query Params | application/json |
请求参数
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
userID | string | acd5455e44fc5bb55 | 用户 ID |
unitID | string | acff-adebc125e45b | 文档 ID |
请求示例:
curl -X GET "http://sample.univer.ai/role?unitID=acff-adebc125e45b&userID=acd5455e44fc5bb55"
响应数据
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
userID | string | acd5455e44fc5bb55 | 请求中的用户 ID |
role | string | editor | 用户在文档上的权限角色,Univer 定义了 3 种角色:owner、editor、reader |
响应示例:
{
"userID": "acd5455e44fc5bb55",
"role": "editor"
}
获取文档的所有协作者
调用场景
在前端设置子表、保护选区的可读取/编辑用户时,需要获取此文档的协作者(只有此文档的协作者才能被设置成子表、保护选区的可读取/编辑用户)
交互流程
协议定义
HTTP 方法 | Headers | 传参方式 | 响应数据格式 |
---|---|---|---|
POST | 无自定义 header,也不会透传用户请求的 header | Body: raw Json | application/json |
请求参数
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
unitIDs | array[string] | [“unit_id1”, “unit_id2”] | 文档 ID 数组 |
请求示例:
{
"unitIDs": [
"unit_id1",
"unit_id2",
"unit_id3"
]
}
响应数据
字段名 | 类型 | 示例值 | 描述 |
---|---|---|---|
collaborators | array[collaboratorList] | 每篇文档的协作者对象列表 | |
collaboratorList.unitID | string | acdf455e5f452 | 文档 ID |
collaboratorList.subjects | array[subjectInfo] | 某一文档的协作者对象列表 | |
subjectInfo.role | string | editor | 协作者的权限角色 |
subjectInfo.subject | Object | 协作者信息 | |
subject.type | string | user | 只能设置为 "user" |
subject.id | string | acdef12555b12 | 用户 ID |
subject.name | string | alice | 用户名字 |
subject.avatar | string | https://image.ai/36554 | 用户头像 |
响应示例:
{
"collaborators": [
{
"unitID":"unit_id1",
"subjects": [
{
"subject": {
"id": "1",
"name": "alice",
"avatar": "https://image.ai/36554",
"type": "user"
},
"role":"owner"
},
{
"subject": {
"id": "2",
"name": "bob",
"avatar": "https://image.ai/36559",
"type": "user"
},
"role":"editor"
},
]
}
]
}
配置 USIP 接入
如何配置 Univer 后端服务启用用户身份认证和权限校验?
使用 docker compose 部署时,在自定义的配置文件 .env.custom
中添加以下配置:
# usip about
USIP_ENABLED=true # 设置为 true 以启用 USIP
USIP_URI_CREDENTIAL=https://your-domain/usip/credential # 配置好身份认证 USIP 的实现 URL
USIP_URI_USERINFO=https://your-domain/usip/userinfo # 配置好用户信息获取 USIP 的实现 URL
USIP_URI_ROLE=https://your-domain/usip/role # 配置好权限角色获取 USIP 的实现 URL
USIP_URI_COLLABORATORS=https://your-domain/usip/collaborators # 配置好协作者列表 USIP 的实现 URL
# auth about
AUTH_PERMISSION_ENABLE_OBJ_INHERIT=false # 见下面权限设计说明
AUTH_PERMISSION_CUSTOMER_STRATEGIES= # 见下面权限设计说明
使用 k8s 部署时,编辑你的自定义 values.yaml,添加以下配置:
universer:
config:
usip:
enabled: true # 设置为 true 以启用 USIP
uri:
userinfo: "https://your-domain/usip/userinfo" # 配置好用户信息获取 USIP 的实现 URL
collaborators: "https://your-domain/usip/collaborators" # 配置好协作者列表 USIP 的实现 URL
role: "https://your-domain/usip/role" # 配置好权限角色获取 USIP 的实现 URL
credential: "https://your-domain/usip/credential" # 配置好身份认证 USIP 的实现 URL
auth:
permission:
enableObjInherit: false # 见下面权限设计说明
customerStrategies: "" # 见下面权限设计说明
请注意,一旦你配置了开启 USIP,上述的所有 4 个 USIP API 的 url 都需要配置,并且需要你的服务正确实现。如何在部署的时候应用这些配置请参考生产部署。
Univer 权限设计
Univer 的权限控制采用的是 RBAC
模型,目前固定设置了 3 个角色:owner
、editor
、reader
,并且 editor 角色具有 reader 角色的权限、owner 角色又具有 editor 角色和 reader 角色的权限。目前暂未开放自定义角色,但开放了用户可配置各权限点位所需的最低角色。Univer 内置有一份默认生效的配置,如果你没有需要可以什么都不做,如果有需要,你可以配置以覆盖部分权限点位的最低角色要求。
Univer 内置的默认生效的各权限点位及其所需的最低角色如下:
权限点位 | 权限点位枚举值 | 点位含义 | 最低角色要求 | 角色枚举值 |
---|---|---|---|---|
ManageCollaborator | 2 | 邀请 / 删除文档的协作者 | owner | 2 |
Copy | 6 | 拷贝文档内容 | reader | 0 |
3 | 打印 | editor | 1 | |
Duplicate | 4 | 复制文档 | editor | 1 |
Share | 7 | 分享给他人 | reader | 0 |
Export | 8 | 导出 | editor | 1 |
Comment | 5 | 评论 | reader | 0 |
View | 0 | 阅读 | reader | 0 |
MoveSheet | 25 | 移动 workbook 内的 worksheet | editor | 1 |
DeleteSheet | 26 | 删除 worksheet | editor | 1 |
HideSheet | 27 | 隐藏 worksheet | editor | 1 |
CopySheet | 28 | 复制 worksheet | editor | 1 |
RenameSheet | 29 | 重命名 worksheet | editor | 1 |
CreateSheet | 30 | 新增 worksheet | editor | 1 |
SetCellStyle | 33 | 设置单元格样式 | editor | 1 |
SetCellValue | 34 | 设置单元格值 | editor | 1 |
InsertHyperlink | 16 | 插入超链接 | editor | 1 |
Sort | 17 | 排序 | editor | 1 |
Filter | 18 | 过滤 | editor | 1 |
PivotTable | 19 | 透视表 | editor | 1 |
RecoverHistory | 43 | 恢复文档到历史版本 | editor | 1 |
ViewHistory | 44 | 查看文档编辑历史记录 | reader | 0 |
SelectProtectedCells | 31 | 选择被保护区域的单元格 | editor | 1 |
SelectUnProtectedCells | 32 | 选择非保护区域的单元格 | editor | 1 |
SetRowStyle | 35 | 设置行样式 | editor | 1 |
SetColumnStyle | 36 | 设置列样式 | editor | 1 |
InsertRow | 37 | 插入行 | editor | 1 |
InsertColumn | 38 | 插入列 | editor | 1 |
DeleteRow | 39 | 删除行 | editor | 1 |
DeleteColumn | 40 | 删除列 | editor | 1 |
Delete | 42 | 删除文档 | owner | 2 |
CreatePermissionObject | 45 | 创建保护区 / 保护子表 | editor | 1 |
如果你想要修改其中一些权限点位要求的最低角色,比如,想设置只有文档 owner(role=2) 才能复制内容(action=6)和打印(action=3),可如下配置:
使用 docker compose 部署时,在自定义的配置文件 .env.custom
中添加以下配置:
AUTH_PERMISSION_CUSTOMER_STRATEGIES=[{"action": 3, "role": 2}, {"action": 6, "role": 2}]
使用 k8s 部署时,编辑你的自定义 values.yaml,添加以下配置:
universer:
config:
auth:
permission:
customerStrategies: '[ {"action": 3, "role": 2}, {"action": 6, "role": 2} ]'
可以看到,配置的值是一个 json 对象数组,对象的 action 即为上述列表中的权限点位枚举值,role 则是该权限点位要求的最低角色对应的枚举值。
Univer 权限管理设计还有一个需要关注的点:
Univer 除了在整个文档级别控制权限,还会在文档下的保护区域 / 子表上控制权限,他们都拥有独立的授权用户管理。比如,用户 A 是整个文档的 editor,但不是此文档中某个保护区域 / 子表的 editor 或 wner,那么用户 A 不能编辑此保护区域 / 子表。在 Univer 的默认配置下,即使用户 A 是文档的 owner,也无法管理其他用户在此文档上创建的保护区域 / 子表,除非其他用户给他添加了保护区域 / 子表的权限。如果你想要配置成文档的 owner 无条件拥有文档中所有对象的 owner 角色,可以如下修改配置:
使用 docker compose 部署时,在自定义的配置文件 .env.custom
中添加以下配置:
AUTH_PERMISSION_ENABLE_OBJ_INHERIT=true
使用 k8s 部署时,编辑你的自定义 values.yaml,添加以下配置:
universer:
config:
auth:
permission:
enableObjInherit: true