客户端exe-API接口文档.md 27 KB

客户端 exe API 接口文档


文档说明

  • 版本: v1.0.4
  • 状态: 草稿(接口逐个调试后更新为正式)
  • 最后更新: 2026-02-16
  • 适用范围: 游铛铛客户端(client-tauri)与后端(backend-client)对接
  • 使用方式: 调试通过一个接口后,在本文档中补充/修正该接口的规范,并勾选调试状态。

1. 概述

1.1 文档目的

  • 统一客户端 exe 与后端 API 的接口约定(入参、出参、明文/密文、错误码)。
  • 作为联调与回归测试的规范依据。
  • 调试过程中将「实际约定」写入本文档,避免口口相传或散落代码注释。

1.2 接口分类

分类 说明 典型接口
认证相关 登录、注册、登出、充值、解绑 login, register, logout, recharge, unbind
公告 通知公告列表(公开) get_announcements
心跳与配置 心跳、客户端配置 heartbeat, config/client
密钥与安全 RSA 公钥、HMAC、密钥同步 keys/public, keys/sync, keys/hmac
用户信息 用户资料 user/profile
Steam 账号 账号 CRUD steam/accounts

1.3 通信方式说明

  • 明文: HTTP 请求/响应体为明文 JSON,无 AES/RSA 加密。
  • 密文(安全端点): 请求体为 AES 加密 + RSA 加密 AES 密钥,响应体可为明文或加密(以各接口说明为准)。时间戳、nonce、HMAC 等按《安全通信规范》执行。

1.4 基础信息

项目 说明
后端 Base URL 客户端配置的 API Base URL,如 https://api.example.com
路由前缀 /api/v1(backend-client 挂载在 /api/v1)
统一响应码 code: 200 成功,4xx/5xx 失败;msg: 用户可读提示;data: 业务数据(可选)

1.5 CLIENT_SECRET 与 SERVER_SECRET(HMAC 签名密钥)

密文安全端点使用双向 HMAC 签名:请求由客户端用 CLIENT_SECRET 签名、服务端验签;响应由服务端用 SERVER_SECRET 签名、客户端验签。二者用途见下表。

密钥 用途 谁签名 谁验签
CLIENT_SECRET 请求完整性 + 请求来源校验 客户端 服务端
SERVER_SECRET 响应完整性 + 响应来源校验 服务端 客户端

是否固定 / 默认格式

  • 采用固定格式、年份动态:默认密钥不再写死为 2024,而是当前年份,与当年部署一致。
    • CLIENT_SECRET 默认:buff-client-secret-{当前年}(如 2026 年即为 buff-client-secret-2026)
    • SERVER_SECRET 默认:buff-server-secret-{当前年}
  • 客户端(Rust):每次请求时用 chrono::Utc::now().year() 拼出上述字符串,无固定密钥字符串存在于二进制中。
  • 服务端:每次验签/签名时用 datetime.now().year 拼出默认值(跨年无需重启);可通过环境变量覆盖。
    • BUFF_API_CLIENT_SECRET:未设置时使用 buff-client-secret-{当前年}。
    • BUFF_API_SERVER_SECRET:未设置时使用 buff-server-secret-{当前年}。
  • 约定:双方未配置环境变量时,默认一致;跨年无需重启:客户端每次请求、服务端每次验签/签名时均按当前年计算,自动对齐新年份。生产环境仍建议用环境变量设置与默认格式不同的密钥,并妥善保管。

安全说明

  • 年份动态可避免完整密钥以单一固定字符串出现在二进制或仓库中,仅作轻微混淆;格式一旦被识破仍可被还原,不能替代真正的密钥保密。
  • 客户端侧密钥仍可能被逆向或调试获取,不能把“只有合法端知道密钥”当作强安全假设;HMAC 主要保证完整性与提高伪造门槛。
  • 继续依赖 HTTPS、AES+RSA、服务端业务校验等形成多层防护。

2. 通用响应格式

2.1 成功响应

{
  "code": 200,
  "msg": "成功",
  "data": { ... }
}

2.2 错误响应

{
  "code": 401,
  "msg": "用户名或密码错误,请检查后重试。",
  "data": null
}

2.3 常见 code 约定

code 含义 典型 msg
200 成功 成功
400 参数/业务错误 请求参数错误,请检查后重试
401 未认证/认证失败 用户名或密码错误 / 会话已过期
403 无权限/业务拒绝 卡密已过期 / 机器码不匹配 / 账号已被禁用
404 资源不存在 资源未找到
500 服务端异常 系统异常,请稍后重试;若持续发生请联系客服

3. 接口清单与调试状态

以下为接口清单,调试状态 在联调通过后更新为「已调试」并补充备注。

序号 接口名称 HTTP 方法 + 路径 明文/密文 调试状态
1 获取公告列表 GET /api/v1/announcements 明文 已调试
2 用户登录 POST /api/v1/auth/login 密文 待调试
3 用户注册 POST /api/v1/auth/register 密文 待调试
4 用户登出 POST /api/v1/auth/logout 明文 待调试
5 卡密充值 POST /api/v1/auth/recharge 密文 待调试
6 机器解绑 POST /api/v1/auth/unbind 密文 待调试
7 心跳 POST /api/v1/heartbeat 密文 待调试
8 获取用户信息 POST /api/v1/user/profile 密文 待调试
9 获取 RSA 公钥(安全客户端初始化) GET 或 POST /api/v1/keys/public 明文 / 密文握手 待调试
10 密钥版本 GET /api/v1/keys/version 明文 待调试
11 密钥同步(已登录) POST /api/v1/keys/sync 密文 待调试
12 客户端配置 GET /api/v1/config/client 明文 待调试
13 HMAC 密钥同步 POST /api/v1/keys/hmac 明文 待调试
14 Steam 账号列表 GET /api/v1/steam/accounts 待确认 待调试
15 创建 Steam 账号 POST /api/v1/steam/accounts 待确认 待调试
16 更新 Steam 账号 PUT /api/v1/steam/accounts 待确认 待调试
17 删除 Steam 账号 DELETE /api/v1/steam/accounts 待确认 待调试

4. 接口详细规范

以下每个接口按「Tauri 命令(如有)→ HTTP 约定 → 请求 → 响应 → 错误 → 调试备注」书写。调试通过后请在本节补充/修正并更新清单中的调试状态。


4.1 获取公告列表

  • 调试状态: 已调试(文档初稿已按当前实现填写)
项目 说明
Tauri 命令 secure_get_announcements(内部实际请求为明文 GET)
HTTP GET /api/v1/announcements
明文/密文 明文(公告为公开数据)
是否需要登录 否

请求参数(Query)

参数名 类型 必填 默认值 说明
page int 否 1 页码,≥1
page_size int 否 10 每页数量,1~100

请求示例

GET {baseUrl}/api/v1/announcements?page=1&page_size=20

响应 data 结构

{
  "code": 200,
  "msg": "成功",
  "data": {
    "announcements": [
      {
        "id": 1,
        "title": "公告标题",
        "content": "<p>HTML内容</p>",
        "priority": 0,
        "publish_time": "2026-02-15T10:00:00",
        "created_at": "2026-02-15T10:00:00"
      }
    ],
    "total": 100,
    "page": 1,
    "page_size": 20
  }
}

客户端调用方式

  • 前端:secureApiClient.getAnnouncements({ page: 1, page_size: 20 })
  • Rust:secure_get_announcements 内部拼 GET URL 请求后端,解析 data.announcements 等返回给前端

调试备注

  • 无

4.2 用户登录

  • 调试状态: 待调试
项目 说明
Tauri 命令 secure_user_login
HTTP POST /api/v1/auth/login
明文/密文 密文(安全端点)
是否需要登录 否

请求体(加密前业务参数)

参数名 类型 必填 说明
username string 是 用户名
password string 是 密码
raw_machine_info string 是 机器特征(后端据此计算 machine_code,不信任客户端传的 machine_code)

安全约定

  • 请求:AES 加密业务参数,RSA 加密 AES 密钥;时间戳、nonce、签名等按安全规范。
  • 响应:加密或明文(以实际实现为准,调试时在此补充)。

响应 data(解密后)

  • 需包含:user_id、username、session_id、expire_time、days_remaining 等(以实际返回为准,调试时在此补充)。

常见错误

code msg 说明
401 用户名或密码错误
403 卡密已过期 / 机器码不匹配 / 账号已被禁用

调试备注

  • (联调通过后填写:实际请求/响应示例、坑点等)

4.3 用户注册

  • 调试状态: 待调试
项目 说明
Tauri 命令 secure_user_register
HTTP POST /api/v1/auth/register
明文/密文 密文(安全端点:AES 加密业务参数 + RSA 加密 AES 密钥,时间戳、nonce、签名按安全规范)
是否需要登录 否

AES 密钥说明

  • 用户注册(及所有密文安全端点)没有固定的“AES 密钥”。
  • AES 密钥由客户端每次请求随机生成:32 字节(256 位)随机数,对应 AES-256。
  • 流程简述:
    1. 客户端生成随机 aes_key(32 字节);
    2. 用该密钥 AES 加密请求业务参数,得到 encrypted_params(Base64);
    3. 用服务端 RSA 公钥加密该 aes_key,得到 aes_key 字段(Base64);
    4. 请求体携带 encrypted_params、aes_key、key_version、timestamp、nonce、signature;
    5. 服务端用 RSA 私钥解密 aes_key 得到本次请求的 AES 密钥,再解密 encrypted_params 得到明文参数。
  • 因此:AES 密钥不在网络中明文出现,仅以 RSA 加密形式传输;每次请求的 AES 密钥均不同。

请求体(加密前业务参数)

参数名 类型 必填 说明
username string 是 用户名,长度 3~100
password string 是 密码,长度 6~100
email string 否* 邮箱(*客户端登录页注册时设为必填,后端接口仍接受可选)
card_code string 否 卡密;若传则校验并激活,激活后写入用户订阅与到期时间
software_code string 否 软件特征码,由 Rust 端根据本地配置自动注入,用于多软件共用用户表

客户端调用方式

  • 前端:secureApiClient.register({ username, password, email, card_code })
  • Rust:invoke('secure_user_register', { request: { username, password, email: email || '', card_code: card_code || '' } });Rust 内部会追加 software_code 再加密 POST 到后端。

成功响应(解密后)

  • HTTP 200,响应体为密文时解密后结构:
{
  "code": 200,
  "msg": "注册成功",
  "data": {
    "user_id": 1,
    "username": "xxx",
    "expire_time": "2026-03-16T00:00:00",
    "days_remaining": 28
  }
}
  • expire_time、days_remaining 在注册时未使用卡密时为 null / 0。

常见错误

code msg 说明
400 请求参数错误,请检查后重试(如未传 username/password)
400 用户名已存在
400 邮箱已被注册
400 卡密不存在
400 卡密已被使用
400 卡密已过期
400 卡密类型不匹配
400 软件不存在或已禁用
500 系统异常,请稍后重试;若持续发生请联系客服

调试备注

  • 客户端展示时间时请用 formatDate,将返回的 expire_time 等格式化为 YYYY-MM-DD HH:mm:ss(不含 T)。

4.4 用户登出

  • 调试状态: 待调试
项目 说明
Tauri 命令 user_logout(前端通过 secureApiClient 等封装)
HTTP POST /api/v1/auth/logout
明文/密文 明文(请求体 JSON)
是否需要登录 否(凭 session_id 失效会话)

请求体

{
  "session_id": "xxx"
}

响应

  • code: 200 成功,400 失败;msg、data 按后端实现。

调试备注

  • (联调后补充)

4.5 卡密充值

  • 调试状态: 待调试
项目 说明
Tauri 命令 secure_user_recharge
HTTP POST /api/v1/auth/recharge
明文/密文 密文
是否需要登录 否

请求体(加密前)

参数名 类型 必填 说明
username string 是 用户名
password string 是 密码
card_code string 是 卡密

常见错误

code msg 说明
404 卡密不存在
403 卡密已使用/已过期

调试备注

  • (联调后补充)

4.6 机器解绑

  • 调试状态: 待调试
项目 说明
Tauri 命令 secure_user_unbind
HTTP POST /api/v1/auth/unbind
明文/密文 密文
是否需要登录 否

请求体(加密前)

参数名 类型 必填 说明
username string 是 用户名
password string 是 密码
raw_machine_info string 是 机器特征(后端计算 machine_code)

常见错误

code msg 说明
404 用户不存在
401 密码错误

调试备注

  • (联调后补充)

4.7 心跳

  • 调试状态: 待调试
项目 说明
Tauri 命令 由 Rust 心跳服务调用(如 secure_heartbeat_call 等)
HTTP POST /api/v1/heartbeat
明文/密文 密文(安全端点)
是否需要登录 是(session_id + machine_code)

请求体(加密前)

参数名 类型 必填 说明
session_id string 是 会话 ID
machine_code string 是 机器码

响应

  • 成功:可含会话续期、客户端配置等(以实际为准,调试时补充)。
  • 错误:401 会话已过期;403 卡密已到期等。

调试备注

  • (联调后补充)

4.8 获取用户信息

  • 调试状态: 待调试
项目 说明
Tauri 命令 get_user_profile(内部可能走安全端点)
HTTP POST /api/v1/user/profile
明文/密文 密文
是否需要登录 是

请求体(加密前)

  • 含 session_id、machine_code(以实际为准)。

响应(解密后)

  • 含 user_id、username、email、expire_time、days_remaining、status 等。

调试备注

  • (联调后补充)

4.9 获取 RSA 公钥(安全客户端初始化)

RSA 密钥相关接口关系与使用场景

文档中与 RSA 公钥相关的接口有三个,区别与使用场景如下:

接口 是否需要登录 主要用途 典型使用场景
GET /api/v1/keys/public 否 明文获取当前服务端 RSA 公钥 登录前首次获取公钥;或 POST 失败时的回退方式
POST /api/v1/keys/public 否 密文握手获取公钥(请求/响应均加密) 登录前首次获取公钥时优先使用,避免公钥在链路上明文传输
POST /api/v1/keys/sync 是 已登录状态下同步最新公钥 服务端做了密钥轮换后,客户端需拿到新公钥,否则后续密文请求会因 key_version 过旧失败

区别简述:

  • keys/public(GET 与 POST):面向未登录场景,是「安全客户端初始化」的两种实现方式(同一能力,GET 明文、POST 密文握手)。客户端在 App 启动或打开登录页时调用,拿到公钥后才能加密登录/注册等请求。实现上优先 POST,失败则回退 GET。
  • keys/sync:面向已登录场景,需要带 session_id、machine_code 等身份信息。用于服务端 RSA 密钥轮换(如 key_version 升级)后,已在线客户端定期拉取最新公钥并更新本地存储。客户端在心跳中会定时(如每 60 秒)调用本接口,保证长期在线时仍使用有效公钥。

典型时序:

  1. 用户打开客户端 → 调用 GET 或 POST /api/v1/keys/public → 拿到公钥 → 可发起登录/注册等密文请求。
  2. 用户登录成功 → 启动心跳 → 心跳任务中定时调用 POST /api/v1/keys/sync → 若服务端已轮换密钥则更新本地公钥,后续请求使用新 key_version。

客户端在登录前需先调用本接口(keys/public)获取服务端 RSA 公钥,用于后续登录、注册等安全端点的请求加密。支持两种方式:GET(明文) 与 POST(密文握手)。客户端优先使用 POST(带机器特征),失败时回退 GET。

  • 调试状态: 待调试
项目 说明
Tauri 命令 initialize_security_client(内部按需调用 GET 或 POST)
HTTP GET /api/v1/keys/public 或 POST /api/v1/keys/public
明文/密文 GET:明文;POST:请求/响应均为密文握手
是否需要登录 否

方式一:GET /api/v1/keys/public(明文)

请求

  • 无请求体,无 Query 参数。

请求示例

GET {baseUrl}/api/v1/keys/public

成功响应(200)

{
  "code": 200,
  "msg": "获取成功",
  "data": {
    "public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----",
    "key_version": 1,
    "expire_at": "2026-12-31T23:59:59"
  }
}
字段 类型 说明
data.public_key string PEM 格式 RSA 公钥
data.key_version int 密钥版本号,用于后续密文请求的 key_version
data.expire_at string 公钥过期时间(ISO8601),可选

常见错误

code msg 说明
500 系统初始化中,请稍后再试(无活跃密钥或密钥已过期)
500 系统异常,请稍后重试;若持续发生请联系客服

方式二:POST /api/v1/keys/public(密文握手)

用于在未持有公钥时,通过客户端提供的 AES 密钥加密请求与响应,获取公钥并建立安全通道。请求体为明文 JSON,但业务内容(机器特征)经 AES 加密放在 encrypted_params 中。

请求体(JSON 明文)

参数名 类型 必填 说明
encrypted_params string 是 Base64(AES-256-CBC 加密的机器特征字符串)。密钥与 IV:见下。
aes_key string 是 Base64(32 字节客户端 AES 密钥)。服务端用 key[0:32] 为 key,key[16:32] 为 IV 解密 encrypted_params。
timestamp int64 是 当前 Unix 时间戳(秒)
nonce string 是 随机字符串,防重放

AES 加密约定(请求)

  • 客户端生成 32 字节随机 aes_key,用 aes_key[0:32] 为密钥、aes_key[16:32] 为 IV,对机器特征字符串做 AES-256-CBC 加密(PKCS7 填充),结果 Base64 为 encrypted_params。

请求示例

{
  "encrypted_params": "Base64(...)",
  "aes_key": "Base64(32 bytes)",
  "timestamp": 1739692800,
  "nonce": "a1b2c3d4e5f6..."
}

成功响应(200)

响应 data 为密文握手结构,客户端需用请求时提供的 aes_key 解密 encrypted_key 得到响应密钥与 IV,再解密 encrypted_data 得到公钥等信息;并验证 signature(RSA-PSS)。

{
  "code": 200,
  "msg": "获取成功",
  "data": {
    "encrypted_key": "Base64( 服务端用客户端 aes_key 加密的 response_key+response_iv )",
    "encrypted_data": "Base64( 用 response_key/response_iv AES-CBC 加密的 JSON(public_key, key_version, signing_public_key) )",
    "signature": "Base64( RSA-PSS 签名: timestamp:nonce:encrypted_data_b64 )",
    "signing_public_key": "PEM 格式公钥,与 encrypted_data 解密后的 public_key 一致",
    "timestamp": 1739692800,
    "nonce": "a1b2c3d4e5f6..."
  }
}
字段 类型 说明
encrypted_key string 用客户端请求中的 aes_key/iv 加密的 response_key(32B)+response_iv(16B)
encrypted_data string 用 response_key/response_iv AES-CBC 加密的 JSON,含 public_key、key_version、signing_public_key
signature string 服务端用 RSA 私钥对 timestamp:nonce:encrypted_data_b64 的 PSS 签名(Base64)
signing_public_key string PEM 公钥,供客户端验签
timestamp / nonce 与请求回显,用于验签与防重放

常见错误

code msg 说明
400 请求参数错误(缺 encrypted_params / aes_key 等)
400 aes_key 无效(解码后长度不足 32 字节)
400 encrypted_params 无效(解码或解密失败)
500 系统初始化中,请稍后再试
500 系统异常,请稍后重试;若持续发生请联系客服

客户端调用方式

  • 前端:secureApiClient.initializeSecurityClient()(登录前由 App 或登录流程调用)。
  • Rust:invoke('initialize_security_client', { apiUrl, username: null, machineCode });内部 KeyManager 优先 POST(带 machine_info),失败则 GET,成功后公钥写入本地 key_storage。

调试备注

  • (联调后补充)

4.10 获取密钥版本

  • 调试状态: 待调试
项目 说明
HTTP GET /api/v1/keys/version
明文/密文 明文
是否需要登录 否

响应 data

  • 含当前 RSA 密钥版本号等。

调试备注

  • (联调后补充)

4.11 密钥同步(已登录)

  • 调试状态: 待调试

与 4.9 的区别:本接口用于已登录后同步最新 RSA 公钥(如服务端密钥轮换);4.9 的 keys/public 用于未登录时首次获取公钥。三者关系与使用场景见 4.9 开头的「RSA 密钥相关接口关系与使用场景」。

项目 说明
HTTP POST /api/v1/keys/sync
明文/密文 密文(安全端点,需登录)
是否需要登录 是

响应

  • 返回当前服务端 public_key、key_version 等(密文响应,解密后得到)。客户端会更新本地 key_storage,心跳任务中会定时调用本接口以应对服务端密钥轮换。

调试备注

  • (联调后补充)

4.12 获取客户端配置

  • 调试状态: 待调试
项目 说明
Tauri 命令 get_client_configs
HTTP GET /api/v1/config/client
明文/密文 明文
是否需要登录 否

响应 data

  • 客户端相关系统配置(如刷新间隔、功能开关等),结构以实际为准。

调试备注

  • (联调后补充)

4.13 HMAC 密钥同步

  • 调试状态: 待调试
项目 说明
Tauri 命令 sync_hmac_key
HTTP POST /api/v1/keys/hmac
明文/密文 明文(请求体为 username、machine_code)
是否需要登录 否(校验用户名+机器码)

请求体

{
  "username": "xxx",
  "machine_code": "xxx"
}

响应

  • 成功返回 HMAC 相关密钥或票据(以实际为准)。

常见错误

code msg 说明
401 用户不存在/密码错误
403 账号被禁用/机器码不匹配

调试备注

  • (联调后补充)

4.14 Steam 账号列表

  • 调试状态: 待调试
项目 说明
Tauri 命令 get_steam_accounts
HTTP GET /api/v1/steam/accounts(具体以后端路由为准)
明文/密文 待确认
是否需要登录 是(需传 user_id 或 session)

请求

  • 参数以后端为准(如 Query 的 user_id 或 Header 的 session)。

响应 data

  • 列表结构以实际为准。

调试备注

  • (联调后补充)

4.15 创建 Steam 账号

  • 调试状态: 待调试
项目 说明
Tauri 命令 create_steam_account
HTTP POST /api/v1/steam/accounts
明文/密文 待确认
是否需要登录 是

请求体(示例,以实际为准)

  • 含 steam_username、shared_secret、identity_secret、steam_id 等。

调试备注

  • (联调后补充)

4.16 更新 Steam 账号

  • 调试状态: 待调试
项目 说明
Tauri 命令 update_steam_account
HTTP PUT /api/v1/steam/accounts
明文/密文 待确认
是否需要登录 是

调试备注

  • (联调后补充)

4.17 删除 Steam 账号

  • 调试状态: 待调试
项目 说明
Tauri 命令 delete_steam_account
HTTP DELETE /api/v1/steam/accounts
明文/密文 待确认
是否需要登录 是

调试备注

  • (联调后补充)

5. 变更记录

日期 版本 变更说明
2026-02-15 v1.0.0 初稿:总览、通用响应、接口清单、公告接口已填,其余待调试补充
2026-02-16 v1.0.1 补充 4.3 用户注册:请求/响应结构、加密前参数、客户端调用方式、后端返回 data、常见错误码与说明;注明登录页注册时邮箱必填
2026-02-16 v1.0.2 新增 1.5 CLIENT_SECRET 与 SERVER_SECRET:用途、是否固定、默认值、服务端环境变量、客户端常量约定
2026-02-16 v1.0.3 客户端支持动态密钥:config.json 中配置 api.client_secret / api.server_secret,未配置时用内置默认值;文档更新为动态配置说明与示例
2026-02-16 v1.0.4 改回固定模式:默认密钥改为 buff-client-secret-{年} / buff-server-secret-{年},年份为运行时当前年(客户端请求时、服务端启动时);移除 config 中 client_secret/server_secret 配置项

使用建议:每完成一个接口的联调,请在本文档中:

  1. 在「接口清单与调试状态」中将该接口标记为「已调试」;
  2. 在对应「4.x 接口详细规范」中补全请求/响应示例与调试备注;
  3. 在「变更记录」中增加一行变更说明。