Files
heicode-mananger/docs/integration/Heicode-登录接口对接文档.md
T

373 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Heicode 客户端 — 登录接口对接文档
**版本**: v1.0
**生效日期**: 2026-04-30
**状态**: 已上线生产,已通过端到端测试
---
## 1. 概述
本文档描述 Heicode 客户端(桌面/CLI)与 Heicode Manager(即 mcp-server)之间的**登录认证接口**。共 4 个接口,覆盖完整登录生命周期:
| 接口 | 用途 |
| ------------------------ | ----------------------- |
| `POST /api/auth/login` | 账号密码登录,换取 token |
| `GET /api/auth/me` | 校验 token 有效性 + 获取当前用户资料 |
| `POST /api/auth/refresh` | access token 过期时换新的 |
| `POST /api/auth/logout` | 登出(token 加入黑名单) |
> 不在本期范围:注册、找回密码、改密码 — 这些走官网 web 端完成。
---
## 2. 接入信息
### 2.1 Base URL
生产环境通过 Azure APIM 网关接入:
```
https://apimtaiji.azure-api.net/api/mcp
```
完整路径示例:
```
POST https://apimtaiji.azure-api.net/api/mcp/api/auth/login
```
### 2.2 通用请求头
| Header | 必填 | 说明 |
| -------------------------------- | ----------- | -------------- |
| `Content-Type: application/json` | 是(POST/PUT) | 请求体 JSON |
| `Authorization: Bearer <token>` | 受保护接口必填 | 见 §3 |
| `X-Request-Id: <uuid>` | 建议 | 全链路追踪 ID,客户端生成 |
### 2.3 Token 模型
登录成功返回两个 token:
| Token | 用途 | 有效期 |
| ----------------- | ------------------------ | ----- |
| **Access Token** | 调业务接口(含 `/me`、`/logout`) | 24 小时 |
| **Refresh Token** | 仅用于 `/refresh` 换新 access | 7 天 |
JWT claims 包含:`sub`(user_id)、`email`、`role`、`channelId`、`type`(access/refresh)、`iat`、`exp`。
---
## 3. 接口详情
### 3.1 POST /api/auth/login — 登录
**请求**
```http
POST /api/auth/login HTTP/1.1
Content-Type: application/json
{
"email": "user@example.com",
"password": "YourPassword123",
"role": "user"
}
```
字段:
- `email` (string, 必填)
- `password` (string, 必填)
- `role` (string, 必填):Heicode 客户端**固定传 `"user"`**
**成功响应 200**
```json
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
"name": "张三",
"email": "user@example.com",
"role": "user",
"channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6"
}
}
}
```
**错误响应**
| HTTP | 含义 | 客户端处理建议 |
| ---- | ------------------------- | -------------------------------- |
| 401 | 邮箱或密码错误 | 显示"账号或密码错误",让用户重新输入 |
| 403 | 账户已被禁用 | 提示用户联系管理员 |
| 429 | 登录尝试过于频繁(**每 IP 5 次/分钟**) | 显示倒计时;响应头 `Retry-After: 60` 表示秒数 |
| 422 | 请求体校验失败(邮箱格式不合法等) | 检查 `detail` 字段 |
| 500 | 服务异常 | 重试或提示稍后再试 |
**重要:限流规则**
- **每 IP 每分钟最多 5 次**登录尝试(不区分成功失败)
- 超出返回 **429 Too Many Requests**,含 `Retry-After` 头(秒)
- 计数滑动窗口,60 秒后自动恢复
---
### 3.2 GET /api/auth/me — 获取当前用户
客户端**启动时**应调用此接口校验本地缓存的 access token 是否仍有效,并刷新用户信息。
**请求**
```http
GET /api/auth/me HTTP/1.1
Authorization: Bearer <accessToken>
```
**成功响应 200**
```json
{
"success": true,
"data": {
"id": "b00a7b8e-9e8b-463d-9593-a3b4d0006778",
"email": "user@example.com",
"name": "张三",
"role": "user",
"channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6",
"status": "active",
"subscriptionTier": "free",
"lastLoginAt": "2026-04-30T06:38:14.765457"
}
}
```
**错误响应**
| HTTP | 含义 | 客户端处理建议 |
| ---- | --------------------- | ------------------------------------------ |
| 401 | Token 无效/过期/已登出/用户不存在 | 调 `/refresh` 换新 token;若 refresh 也 401,跳登录页 |
| 403 | 账户已被禁用 | 强制登出,提示联系管理员 |
---
### 3.3 POST /api/auth/refresh — 刷新 token
access token 接近或已过期时调用,使用 **refresh token** 换取新的 access + refresh token 对。
**请求**
```http
POST /api/auth/refresh HTTP/1.1
Authorization: Bearer <refreshToken>
```
> ⚠️ **必须传 refresh token**,传 access token 会被拒绝。
**成功响应 200**
```json
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs..."
}
}
```
客户端收到新的 token 对后**应替换本地缓存**(包括 refresh token,旧的也作废)。
**错误响应**
| HTTP | 含义 | 客户端处理建议 |
| ---- | ---------------------------------------- | ------- |
| 401 | refresh token 无效 / 过期 / 错传了 access token | 跳登录页 |
实施细节:
- 服务端会校验 token claims `type == "refresh"`,否则拒绝
- 旧 refresh token 不会被立即吊销(容许并发换发期),但客户端应丢弃旧的
---
### 3.4 POST /api/auth/logout — 登出
将当前 access token 加入黑名单,使其立即失效。
**请求**
```http
POST /api/auth/logout HTTP/1.1
Authorization: Bearer <accessToken>
```
**成功响应 200**
```json
{
"success": true,
"data": null,
"message": "登出成功"
}
```
**错误响应**
logout 容错性较强,token 黑名单写入失败也会返回 200(前端清理本地 token 即可)。
**客户端登出流程**:
1. 调 `/api/auth/logout`
2. 清除本地存储的 access + refresh token
3. 清除当前用户资料缓存
4. 跳转到登录页
---
## 4. 完整登录流程(示例)
### 启动时
```
┌─ 本地有 access token ?
│
├─ 是 ─→ GET /me
│ ├─ 200 ─→ 进入主界面
│ └─ 401 ─→ 本地有 refresh token ?
│ ├─ 是 ─→ POST /refresh
│ │ ├─ 200 ─→ 替换 token,进入主界面
│ │ └─ 401 ─→ 跳登录页
│ └─ 否 ─→ 跳登录页
│
└─ 否 ─→ 跳登录页
```
### 登录页提交
```
POST /login
├─ 200 ─→ 存 token 对,进主界面
├─ 401 ─→ 显示"账号或密码错误"
├─ 429 ─→ 显示"尝试过于频繁,请 N 秒后重试"(N 取响应头 Retry-After)
└─ 其他 ─→ 显示通用错误
```
### 业务请求过程中 access token 过期
```
任意业务接口返回 401
└─→ POST /refresh (用 refresh token)
├─ 200 ─→ 替换 token,重试原请求
└─ 401 ─→ 清理 token,跳登录页
```
### 登出按钮
```
POST /logout
└─→ 不论结果都清理本地 token,跳登录页
```
---
## 5. 错误响应格式
当前为 FastAPI 默认格式(下个版本 `/api/v1/*` 路径会改为标准 envelope,本期保留兼容):
```json
{
"detail": "邮箱或密码错误"
}
```
422 校验错误格式(Pydantic):
```json
{
"detail": [
{
"type": "value_error",
"loc": ["body", "email"],
"msg": "value is not a valid email address: ...",
"input": "abc"
}
]
}
```
---
## 6. 安全注意事项
| 项 | 说明 |
| -------------- | -------------------------------------------------------------------------------------- |
| **token 存储** | 桌面应用建议存到 OS 安全凭据存储(Windows Credential Manager / macOS Keychain / Linux Secret Service) |
| **HTTPS 强制** | 生产 base URL 已是 HTTPS;客户端**禁止**回退 HTTP |
| **token 泄露应对** | 用户怀疑泄露时提示去官网 web 端改密码(改密会导致所有 session 黑名单) |
| **审计日志** | 所有 login 尝试(成功/失败)服务端均写审计 |
| **状态码不泄漏** | 错误信息已统一用"邮箱或密码错误",不区分账号是否存在,防爆破 |
---
## 7. 测试账号(仅供联调)
| 角色 | 邮箱 | 密码 |
| ---- | ----------- | ------------ |
| 普通用户 | `55@55.com` | `By@123456.` |
> ⚠️ 测试账号仅用于联调阶段,正式上线前请务必关闭。
---
## 8. 已上线生产验证清单
| 测试项 | 结果 |
| ------------------------------------------ | --- |
| login 200 + 返回 access/refresh token | ✅ |
| /me 用 access token → 200 + 完整 profile | ✅ |
| /refresh 用 refresh token → 200 + 新 token 对 | ✅ |
| /refresh 用 access token → 401 拒绝 | ✅ |
| logout → 200 | ✅ |
| logout 后旧 token 调 /me → 401(黑名单生效) | ✅ |
| 连续 7 次错密 → 第 6 次起 429(每 IP 5/min 限流) | ✅ |
| 服务器审计日志记录所有 login(含成功/失败) | ✅ |
镜像 digest: `sha256:339b64ae090dc81fa13cb29705958167e77fe0698e27ac227c05054ed5c42309`
镜像 tag: `taiji.azurecr.io/mcp-server:heicode-auth-fix2-20260430`
部署日期: 2026-04-30
---
## 9. 联系
如对接过程发现接口行为与本文档不一致,请联系 Heicode Manager 后端团队,附上:
- 请求完整 URL / Headers / Body
- 响应 HTTP 状态 + Body
- `X-Request-Id` 头值(便于服务端按 ID 反查日志)