# 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 ` | 受保护接口必填 | 见 §3 | | `X-Request-Id: ` | 建议 | 全链路追踪 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 ``` **成功响应 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 ``` > ⚠️ **必须传 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 ``` **成功响应 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 反查日志)