feat: add legacy device migration flow
This commit is contained in:
+35
@@ -19,6 +19,7 @@
|
||||
- API Key 库内只存 `key_hash`(SHA-256)与 `key_prefix`,明文只在创建时返回一次,不在 admin、日志或调用记录中回显。
|
||||
- 每次生成调用写 `CallRecord`;只允许保存 `result_ref` / `result_summary` 这类引用或摘要,不保存 provider `raw`、base64 图片或敏感上游字段。
|
||||
- T-624/T-625 起,蝦皮圈客户端可先用 API Key 登记设备并取得短期 `X-Device-Session`;标题、图片、异步图片提交和图片理解可选携带该头,服务端只把已验证的设备关联到本次 `CallRecord` 与白名单遥测。没有该头的旧客户端继续按原 API Key 路径调用,响应、计费、任务提交和轮询均不变;设备会话尚**不**参与订阅授权拦截。设备标识、公钥和会话令牌不写入调用日志或响应中的设备对象。
|
||||
- T-627 起,存量迁移客户端可用旧 API Key 加当前 `X-Device-Session` 申请短时迁移请求;仍必须由同账号网页登录确认后才绑定席位并签发产品专用设备凭证。凭证明文只在申请响应出现一次,数据库仅存 hash;旧 API Key 本身不能绕过网页登录确认,也不改变既有生成接口。
|
||||
|
||||
T-301 已实现对外 API 鉴权基线:`apps.api.authentication.ApiKeyAuthentication` 只解析 `Authorization: Bearer <API_KEY>`;生成、余额等外部 API 视图应继承 `apps.api.views.ExternalApiView`,不接受 Web session。
|
||||
|
||||
@@ -92,6 +93,12 @@ T-607/T-609/T-617 已实现 `GET /api/v1/client/releases/latest?platform=windows
|
||||
| `device_session_invalid` | 缺失、无效或过期设备会话 | 401 |
|
||||
| `device_revoked` | 客户端设备已被吊销 | 403 |
|
||||
| `device_mismatch` | 设备会话不属于当前 API Key 所属账号 | 403 |
|
||||
| `device_session_required` | 存量迁移申请缺少当前设备会话 | 401 |
|
||||
| `migration_not_eligible` | 当前账号没有有效存量迁移资格 | 403 |
|
||||
| `migration_request_not_found` | 迁移请求不存在或不属于当前设备 | 404 |
|
||||
| `migration_request_expired` | 迁移请求已过期或不可用 | 400 |
|
||||
| `migration_request_forbidden` | 网页确认账号不属于迁移请求 | 403 |
|
||||
| `device_credential_exists` | 当前设备已完成迁移绑定 | 400 |
|
||||
| `device_identity_mismatch` | 同一设备标识对应的安装公钥不一致 | 403 |
|
||||
|
||||
`upstream_timeout` 与 `upstream_error` 都表示本次生成失败且已退点,客户端可按失败 / 重试处理。`upstream_timeout` 通常来自 T-612 的生图上游硬截止或底层 HTTP 超时。`upstream_error` 需要按错误消息继续区分:如果 `/api/v1/balance` 成功、`/api/v1/models` 中目标别名存在且 `pricing_status="priced"`,但生成接口返回 `502 upstream_error` 且消息为「上游模型配置不可用」,优先判定为**服务端上游模型运行配置问题**,不是客户端 payload 问题。常见原因是 `AI_KEY_ENCRYPTION_KEY` 与入库时不一致、`AiModel.api_key_encrypted` 无法解密、别名指向的 `AiModel` 缺 `url` / `model` / `api_type` / API Key,或 `api_type` 无可用 Provider。该错误路径不应最终扣点;修复按 [`deployment.md`](deployment.md) 的 AI 模型配置排查步骤执行。
|
||||
@@ -195,6 +202,34 @@ X-Device-Session: dvs_cmhub_<device_session_token>
|
||||
|
||||
成功响应返回当前设备公开摘要、会话到期时间和 `activity_updated`。默认同一设备至少间隔 24 小时才写入一次 `last_seen_at`,因此频繁心跳可能返回 `activity_updated=false`,这是正常行为。缺失、无效或过期会话返回 `401 device_session_invalid`;已吊销设备返回 `403 device_revoked`。该接口不扣点、不创建调用记录,也不刷新过期会话;客户端应重新调用登记接口获取新令牌。
|
||||
|
||||
### `POST /api/v1/client/migration-requests`
|
||||
|
||||
存量蝦皮圈客户端发起设备迁移确认请求。需要既有 API Key 和当前设备会话;该接口不扣点、不调用上游、不改变旧生成接口。
|
||||
|
||||
```http
|
||||
POST /api/v1/client/migration-requests
|
||||
Authorization: Bearer sk_cmhub_xxx
|
||||
X-Device-Session: dvs_cmhub_<device_session_token>
|
||||
```
|
||||
|
||||
响应中的 `device_credential_token` 是设备凭证明文,只返回本次一次,客户端必须安全保存且不得写入日志;后台只存 hash。用户打开 `confirmation_url` 后登录同一账号并确认,才会实际占用席位、签发凭证。没有后台显式创建的 `LegacyMigrationGrant` 时返回 `403 migration_not_eligible`;没有会话返回 `401 device_session_required`。
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id": "0f70303b-6ec1-4ea1-8c0c-7c6d9dd7ae17",
|
||||
"status": "pending",
|
||||
"product_code": "cmshopee",
|
||||
"expires_at": "2026-07-21T12:15:00+08:00",
|
||||
"confirmed_at": null,
|
||||
"confirmation_url": "https://cm.example.com/migration/confirm/0f70303b-6ec1-4ea1-8c0c-7c6d9dd7ae17",
|
||||
"device_credential_token": "dvc_cmhub_<one_time_secret>"
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/client/migration-requests/{request_id}`
|
||||
|
||||
客户端以同一 API Key 和当前设备会话轮询迁移状态。只返回请求状态、产品、时间和确认链接,**不会**再次返回设备凭证明文;跨用户或跨设备请求返回 `404 migration_request_not_found`。网页刷新、客户端轮询重试不会重复占用席位或重复签发凭证。
|
||||
|
||||
### 生成接口的可选设备会话
|
||||
|
||||
以下生成提交路由可在既有 `Authorization: Bearer <API_KEY>` 外,额外携带同账号登记得到的设备会话:`POST /api/v1/generate/title`、`POST /api/v1/analyze/images`、`POST /api/v1/generate/image`、`POST /api/v1/generate/image/tasks`。
|
||||
|
||||
Reference in New Issue
Block a user