7a4c516a20
- 后端:新增 CloudSync 认证/权限/端点/服务与 DTO - 数据:新增用户/会话/安全策略实体与 EF Core migrations - 前端:新增云同步设置 UI、客户端与本地存储;Vite 支持 maui 构建输出到 wwwroot - 桌面端:新增 Avalonia 项目、内置 WebServer、托盘与 Windows 全局热键 - 发布/构建:新增 Windows/Linux 发布脚本与统一入口;调整 MAUI 资源与安装包配置 - 文档:同步更新 README/docs 与协作规则
146 lines
4.8 KiB
Markdown
146 lines
4.8 KiB
Markdown
# 04 - 云同步(基础可用):服务端基础能力
|
||
|
||
## 目标(PRD 约束)
|
||
|
||
- 支持用户级任务数据同步/读取(用户隔离)
|
||
- 提供基于角色/权限的访问控制(RBAC)
|
||
- 对高风险操作支持二次认证(能力以服务端实现为准)
|
||
- 下发“可控落盘”配置(服务端配置驱动)
|
||
|
||
## 范围(建议最小闭环)
|
||
|
||
- 认证(登录/会话)
|
||
- 任务数据 API(按用户隔离)
|
||
- 配置下发 API(是否允许落盘、终端可信度/会话策略等)
|
||
- RBAC 最小落地(至少能区分“允许同步/禁止同步”或“只读/读写”)
|
||
- 二次认证最小落地(至少覆盖“启用/关闭同步、切换账号、调整落盘策略”等高风险操作的接口)
|
||
|
||
## 依赖
|
||
|
||
- 与 `05-*`(客户端)可并行推进,但需要尽早冻结 API 契约(字段名/响应结构/错误码)
|
||
|
||
## 接口契约(需要在实现前先写清楚)
|
||
|
||
v1.2.0 已实现一套最小可用契约(用于 05/06 客户端对接时冻结字段名/错误码)。
|
||
|
||
### 通用约定
|
||
|
||
- Base URL:由客户端配置(例如 `https://{host}:{port}`)
|
||
- 认证:`Authorization: Bearer {accessToken}`
|
||
- 错误响应(统一结构):
|
||
|
||
```json
|
||
{ "code": "ERROR_CODE", "message": "Human readable message." }
|
||
```
|
||
|
||
### 错误码
|
||
|
||
- `UNAUTHORIZED`:未登录或会话失效
|
||
- `FORBIDDEN`:权限不足(RBAC / 策略拒绝)
|
||
- `SECOND_FACTOR_REQUIRED`:需要二次认证(step-up)
|
||
- `BAD_REQUEST`:请求参数不合法
|
||
- `NOT_FOUND`:资源不存在
|
||
|
||
### Auth
|
||
|
||
- 初始化管理员(仅当系统尚无云用户时允许一次):
|
||
- `POST /auth/bootstrap`
|
||
- Body:`{ "userName": "admin", "password": "..." }`
|
||
- 200:成功;403:已初始化或不允许
|
||
|
||
- 登录:
|
||
- `POST /auth/login`
|
||
- Body:`{ "userName": "admin", "password": "..." }`
|
||
- 200:`{ accessToken, expiresAtUtc, userId, role, permissions[] }`
|
||
|
||
- 二次认证(step-up,v1.2.0 最小实现为“复用登录口令进行再认证”):
|
||
- `POST /auth/step-up`
|
||
- Header:`Authorization: Bearer ...`
|
||
- Body:`{ "password": "..." }`
|
||
- 200:`{ stepUpExpiresAtUtc }`
|
||
|
||
### Tasks
|
||
|
||
- 获取当前用户任务全量:
|
||
- `GET /tasks`
|
||
- Header:`Authorization: Bearer ...`
|
||
- 权限:`tasks:read`
|
||
- 200:`CloudTaskItem[]`
|
||
|
||
### Sync
|
||
|
||
- 上传/同步(增删改后返回最新全量):
|
||
- `POST /sync`
|
||
- Header:`Authorization: Bearer ...`
|
||
- 权限:`sync:write`
|
||
- 二次认证:必需(否则返回 `SECOND_FACTOR_REQUIRED`)
|
||
- Body:
|
||
|
||
```json
|
||
{
|
||
"upserts": [
|
||
{ "id": 1, "title": "A", "priority": 1, "isCompleted": false, "parentTaskId": null },
|
||
{ "id": null, "title": "New", "priority": 1, "isCompleted": false, "parentTaskId": null }
|
||
],
|
||
"deletes": [2, 3]
|
||
}
|
||
```
|
||
|
||
- 200:
|
||
|
||
```json
|
||
{
|
||
"serverTimeUtc": "2026-04-06T17:39:30.0281279Z",
|
||
"tasks": [ /* CloudTaskItem[] */ ]
|
||
}
|
||
```
|
||
|
||
### Security Policy
|
||
|
||
- 获取安全策略(服务端下发):
|
||
- `GET /security/policy`
|
||
- Header:`Authorization: Bearer ...`
|
||
- 权限:`policy:read`
|
||
- 200:
|
||
|
||
```json
|
||
{
|
||
"allowPersist": true,
|
||
"allowSync": true,
|
||
"requireSecondFactorFor": ["sync:write", "policy:write"]
|
||
}
|
||
```
|
||
|
||
- 更新安全策略(高风险操作):
|
||
- `PUT /security/policy`
|
||
- Header:`Authorization: Bearer ...`
|
||
- 权限:`policy:write`
|
||
- 二次认证:必需(否则返回 `SECOND_FACTOR_REQUIRED`)
|
||
- Body:`{ "allowPersist": false, "allowSync": false }`
|
||
|
||
## 关键实现点(建议)
|
||
|
||
1. 用户隔离
|
||
- 服务端所有读写必须绑定当前登录用户上下文
|
||
2. 权限模型(RBAC)
|
||
- 定义最小角色:例如 `user`、`admin`
|
||
- 定义最小权限:例如 `tasks:read`、`tasks:write`、`sync:enable`
|
||
3. 二次认证
|
||
- 选择实现方式(示例):二次口令/一次性验证码(TOTP)/短信(若无能力则先实现“二次口令”)
|
||
- 能力不足时必须返回明确错误,使客户端可提示用户
|
||
4. 落盘策略下发
|
||
- 支持按用户或按会话/终端下发
|
||
- 默认策略建议为“允许落盘”,便于可用性;但需支持“禁止落盘”
|
||
|
||
## 验收标准
|
||
|
||
- 使用不同用户登录后获取任务,数据严格隔离
|
||
- 未授权角色/权限访问受限接口会被拒绝(错误响应可被客户端识别)
|
||
- 能返回安全策略配置(至少包含 `allowPersist`),并可通过配置切换行为
|
||
|
||
## 当前实现说明(v1.2.0)
|
||
|
||
- 数据隔离:`Tasks` 表新增 `UserId` 外键,云端 API 的所有读写按当前会话用户隔离;本地模式使用固定的 `local` 用户 ID(不影响既有 Dynamic API)。
|
||
- RBAC:内置 `admin / user / readonly / nosync` 角色与权限映射;并叠加 `SecurityPolicies.AllowSync` 作为“是否允许同步写入”的策略开关。
|
||
- 二次认证:通过 `POST /auth/step-up` 将会话提升到 step-up 状态;`POST /sync` 与 `PUT /security/policy` 会强制要求 step-up。
|