119 lines
4.4 KiB
Markdown
119 lines
4.4 KiB
Markdown
# 设备与登录 — 客户端对接说明
|
||
|
||
面向 iOS / Android / Web 等客户端
|
||
|
||
## 变更摘要(Breaking)
|
||
|
||
| 项 | 旧行为 | 新行为 |
|
||
| --- | --- | --- |
|
||
| 登录 Body `device_id` | 客户端生成并必填 | **删除**;由服务端根据物理指纹生成 |
|
||
| 登录 Body | 无 | **`app_id` 必填**;**`device_type` 为整数 1–6**(见 meta) |
|
||
| 物理标识 | 无 | **`idfv`(iOS/macOS)或 `android_id`(Android/Harmony)** 按平台必填 |
|
||
| JWT | `sub` + `did` | 增加 **`aid`(app_id)**;access / refresh 均含 |
|
||
| 登录响应 `data` | `device_id` | 仍为服务端 **`device_id`**,并增加 **`app_id`** |
|
||
| 同一邮箱 | 同一用户 | 不变 |
|
||
| 同机多 App | 各 App 各自 `device_id` | **同机共用一个 `device_id`**;会话按 **`app_id` / JWT `aid`** 区分 |
|
||
|
||
## 登录 `POST /v1/auth/login`
|
||
|
||
### 必填字段
|
||
|
||
- `email`、`verify_code`
|
||
- `app_id`:例如 Spark IM 为 `1`(以 meta 枚举为准)
|
||
- `device_type`:**整数枚举**(见 `GET /v1/meta/enums` → `device_type`);`1`=ios,`2`=android,`3`=harmony,`4`=windows,`5`=macos,`6`=web。可选 **`platform`** 同枚举,仅当未传 `device_type` 时作别名。
|
||
|
||
### 物理设备字段(生成 `device_id`)
|
||
|
||
| `device_type` | 必填 Body 字段 |
|
||
| --- | --- |
|
||
| `1`(ios)、`5`(macos) | `idfv` |
|
||
| `2`(android)、`3`(harmony) | `android_id` |
|
||
| `4`(windows)、`6`(web) | `idfv` 或 `android_id` 至少一个(建议 Web 用稳定 local id 映射到其一) |
|
||
|
||
可选:`device_name`(展示名)。
|
||
|
||
**不要**再传 `device_id`。指纹算法(与客户端实现一致即可):
|
||
|
||
```text
|
||
payload = "{device_type}:{idfv|android_id}"
|
||
fingerprint_hash = HEX(SHA256(payload))
|
||
device_id = uint64(SHA256(fingerprint_hash)[0:8]),非 0
|
||
```
|
||
|
||
`device_type` 与 meta / DB / 指纹 **同一套数值**(ios=1, android=2, …)。
|
||
|
||
### 响应
|
||
|
||
保存:
|
||
|
||
- `access_token`、`refresh_token`
|
||
- **`device_id`**(写入本地,与 JWT `did` 相同)
|
||
- **`app_id`**(与 JWT `aid` 相同)
|
||
- `user_id`、`spark_id`
|
||
|
||
### 示例
|
||
|
||
```http
|
||
POST /v1/auth/login HTTP/1.1
|
||
Content-Type: application/json
|
||
X-Language: zh-CN
|
||
X-App-Version: 1.0.0
|
||
|
||
```
|
||
|
||
## JWT
|
||
|
||
解码 access / refresh token(HS256,生产由服务端签发):
|
||
|
||
| claim | 含义 |
|
||
| --- | --- |
|
||
| `sub` | `user_id` |
|
||
| `did` | `device_id`(服务端生成) |
|
||
| **`aid`** | **`app_id`(当次登录 App)** |
|
||
| `use` | `access` 或 `refresh` |
|
||
|
||
刷新 token 后 **`aid` 不变**(与首次登录 App 绑定)。
|
||
|
||
## 登录后的 HTTP
|
||
|
||
- **`Authorization: Bearer <access_token>`**(必填)
|
||
- **`X-Device-ID`**:十进制 `device_id`,须等于 JWT **`did`**(与登录响应一致)
|
||
- 可选 **`X-App-ID`**:若传,须与 JWT **`aid`** 一致
|
||
- **`X-Language` / `Accept-Language`**、`X-App-Version` 仍走 Header
|
||
|
||
业务 JSON **不要**再塞 `device_id` / `app_id`(登录、刷新除外)。
|
||
|
||
## 刷新与注销
|
||
|
||
- **`POST /v1/auth/token/refresh`**:Body 仅 `refresh_token`;新 token 对仍带相同 `did` / `aid`。
|
||
- **`POST /v1/auth/logout`**:吊销当前 **`(user, device, app)`** 会话(默认服务端配置下各 App 独立;若运维切到 `pair` 模式,同设备会互踢 refresh,见下)。
|
||
|
||
## TCP AUTH
|
||
|
||
- Body:`token`(access)、可选 **`device_id`**(须等于 JWT `did`)、`app_version`、`language`
|
||
- **不必**在 AUTH Body 传 `app_id`;以 token 内 **`aid`** 为准
|
||
- 连接仍按 **`(user_id, device_id)`** 绑定;同机多 App 各连各的 token 即可
|
||
|
||
## 同机多 App
|
||
|
||
- **同一物理机 → 同一 `device_id`**(指纹不含 `app_id`)
|
||
- **不同 App → 不同 JWT `aid`**,各自 login 拿各自 token
|
||
- 默认(`triple`):App A 与 App B **可同时** refresh,互不踢
|
||
- 若服务端改为 `pair` 模式:后登录 App 会 **踢掉同设备上其它 App 的 refresh**(需产品公告)
|
||
|
||
## 客户端迁移清单
|
||
|
||
1. 登录 Body:加 **`app_id`**、**`idfv` / `android_id`**;去掉自研 **`device_id`**
|
||
2. 首次登录成功后 **持久化响应里的 `device_id`**,后续 Header / TCP 使用该值
|
||
3. 解析 JWT 时读取 **`aid`**,多 App 共用一套 `device_id` 存储键时应用 **`(device_id, app_id)`** 区分 token
|
||
4. 拉取 **`GET /v1/meta/enums`** 获取 `app_id`、`device_type` 等
|
||
|