文档说明
| 分类 | 说明 | 典型接口 |
|---|---|---|
| 认证相关 | 登录、注册、登出、充值、解绑 | login, register, logout, recharge, unbind |
| 公告 | 通知公告列表(公开) | get_announcements |
| 心跳与配置 | 心跳、客户端配置 | heartbeat, config/client |
| 密钥与安全 | RSA 公钥、HMAC、密钥同步 | keys/public, keys/sync, keys/hmac |
| 用户信息 | 用户资料 | user/profile |
| Steam 账号 | 账号 CRUD | steam/accounts |
| 项目 | 说明 |
|---|---|
| 后端 Base URL | 客户端配置的 API Base URL,如 https://api.example.com |
| 路由前缀 | /api/v1(backend-client 挂载在 /api/v1) |
| 统一响应码 | code: 200 成功,4xx/5xx 失败;msg: 用户可读提示;data: 业务数据(可选) |
密文安全端点使用双向 HMAC 签名:请求由客户端用 CLIENT_SECRET 签名、服务端验签;响应由服务端用 SERVER_SECRET 签名、客户端验签。二者用途见下表。
| 密钥 | 用途 | 谁签名 | 谁验签 |
|---|---|---|---|
| CLIENT_SECRET | 请求完整性 + 请求来源校验 | 客户端 | 服务端 |
| SERVER_SECRET | 响应完整性 + 响应来源校验 | 服务端 | 客户端 |
是否固定 / 默认格式
buff-client-secret-{当前年}(如 2026 年即为 buff-client-secret-2026)buff-server-secret-{当前年}chrono::Utc::now().year() 拼出上述字符串,无固定密钥字符串存在于二进制中。datetime.now().year 拼出默认值(跨年无需重启);可通过环境变量覆盖。
BUFF_API_CLIENT_SECRET:未设置时使用 buff-client-secret-{当前年}。BUFF_API_SERVER_SECRET:未设置时使用 buff-server-secret-{当前年}。安全说明
{
"code": 200,
"msg": "成功",
"data": { ... }
}
{
"code": 401,
"msg": "用户名或密码错误,请检查后重试。",
"data": null
}
| code | 含义 | 典型 msg |
|---|---|---|
| 200 | 成功 | 成功 |
| 400 | 参数/业务错误 | 请求参数错误,请检查后重试 |
| 401 | 未认证/认证失败 | 用户名或密码错误 / 会话已过期 |
| 403 | 无权限/业务拒绝 | 卡密已过期 / 机器码不匹配 / 账号已被禁用 |
| 404 | 资源不存在 | 资源未找到 |
| 500 | 服务端异常 | 系统异常,请稍后重试;若持续发生请联系客服 |
以下为接口清单,调试状态 在联调通过后更新为「已调试」并补充备注。
| 序号 | 接口名称 | 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 | 待确认 | 待调试 |
以下每个接口按「Tauri 命令(如有)→ HTTP 约定 → 请求 → 响应 → 错误 → 调试备注」书写。调试通过后请在本节补充/修正并更新清单中的调试状态。
| 项目 | 说明 |
|---|---|
| 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 })secure_get_announcements 内部拼 GET URL 请求后端,解析 data.announcements 等返回给前端调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | secure_user_login |
| HTTP | POST /api/v1/auth/login |
| 明文/密文 | 密文(安全端点) |
| 是否需要登录 | 否 |
请求体(加密前业务参数)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| raw_machine_info | string | 是 | 机器特征(后端据此计算 machine_code,不信任客户端传的 machine_code) |
安全约定
响应 data(解密后)
user_id、username、session_id、expire_time、days_remaining 等(以实际返回为准,调试时在此补充)。常见错误
| code | msg 说明 |
|---|---|
| 401 | 用户名或密码错误 |
| 403 | 卡密已过期 / 机器码不匹配 / 账号已被禁用 |
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | secure_user_register |
| HTTP | POST /api/v1/auth/register |
| 明文/密文 | 密文(安全端点:AES 加密业务参数 + RSA 加密 AES 密钥,时间戳、nonce、签名按安全规范) |
| 是否需要登录 | 否 |
AES 密钥说明
aes_key(32 字节);encrypted_params(Base64);aes_key,得到 aes_key 字段(Base64);encrypted_params、aes_key、key_version、timestamp、nonce、signature;aes_key 得到本次请求的 AES 密钥,再解密 encrypted_params 得到明文参数。请求体(加密前业务参数)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名,长度 3~100 |
| password | string | 是 | 密码,长度 6~100 |
| string | 否* | 邮箱(*客户端登录页注册时设为必填,后端接口仍接受可选) | |
| card_code | string | 否 | 卡密;若传则校验并激活,激活后写入用户订阅与到期时间 |
| software_code | string | 否 | 软件特征码,由 Rust 端根据本地配置自动注入,用于多软件共用用户表 |
客户端调用方式
secureApiClient.register({ username, password, email, card_code })invoke('secure_user_register', { request: { username, password, email: email || '', card_code: card_code || '' } });Rust 内部会追加 software_code 再加密 POST 到后端。成功响应(解密后)
{
"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)。| 项目 | 说明 |
|---|---|
| Tauri 命令 | user_logout(前端通过 secureApiClient 等封装) |
| HTTP | POST /api/v1/auth/logout |
| 明文/密文 | 明文(请求体 JSON) |
| 是否需要登录 | 否(凭 session_id 失效会话) |
请求体
{
"session_id": "xxx"
}
响应
code: 200 成功,400 失败;msg、data 按后端实现。调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | secure_user_recharge |
| HTTP | POST /api/v1/auth/recharge |
| 明文/密文 | 密文 |
| 是否需要登录 | 否 |
请求体(加密前)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| card_code | string | 是 | 卡密 |
常见错误
| code | msg 说明 |
|---|---|
| 404 | 卡密不存在 |
| 403 | 卡密已使用/已过期 |
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | secure_user_unbind |
| HTTP | POST /api/v1/auth/unbind |
| 明文/密文 | 密文 |
| 是否需要登录 | 否 |
请求体(加密前)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| raw_machine_info | string | 是 | 机器特征(后端计算 machine_code) |
常见错误
| code | msg 说明 |
|---|---|
| 404 | 用户不存在 |
| 401 | 密码错误 |
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | 由 Rust 心跳服务调用(如 secure_heartbeat_call 等) |
| HTTP | POST /api/v1/heartbeat |
| 明文/密文 | 密文(安全端点) |
| 是否需要登录 | 是(session_id + machine_code) |
请求体(加密前)
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| session_id | string | 是 | 会话 ID |
| machine_code | string | 是 | 机器码 |
响应
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | get_user_profile(内部可能走安全端点) |
| HTTP | POST /api/v1/user/profile |
| 明文/密文 | 密文 |
| 是否需要登录 | 是 |
请求体(加密前)
session_id、machine_code(以实际为准)。响应(解密后)
user_id、username、email、expire_time、days_remaining、status 等。调试备注
文档中与 RSA 公钥相关的接口有三个,区别与使用场景如下:
| 接口 | 是否需要登录 | 主要用途 | 典型使用场景 |
|---|---|---|---|
| GET /api/v1/keys/public | 否 | 明文获取当前服务端 RSA 公钥 | 登录前首次获取公钥;或 POST 失败时的回退方式 |
| POST /api/v1/keys/public | 否 | 密文握手获取公钥(请求/响应均加密) | 登录前首次获取公钥时优先使用,避免公钥在链路上明文传输 |
| 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 {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 | 系统异常,请稍后重试;若持续发生请联系客服 |
用于在未持有公钥时,通过客户端提供的 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 加密约定(请求)
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 或登录流程调用)。invoke('initialize_security_client', { apiUrl, username: null, machineCode });内部 KeyManager 优先 POST(带 machine_info),失败则 GET,成功后公钥写入本地 key_storage。调试备注
| 项目 | 说明 |
|---|---|
| HTTP | GET /api/v1/keys/version |
| 明文/密文 | 明文 |
| 是否需要登录 | 否 |
响应 data
调试备注
与 4.9 的区别:本接口用于已登录后同步最新 RSA 公钥(如服务端密钥轮换);4.9 的 keys/public 用于未登录时首次获取公钥。三者关系与使用场景见 4.9 开头的「RSA 密钥相关接口关系与使用场景」。
| 项目 | 说明 |
|---|---|
| HTTP | POST /api/v1/keys/sync |
| 明文/密文 | 密文(安全端点,需登录) |
| 是否需要登录 | 是 |
响应
public_key、key_version 等(密文响应,解密后得到)。客户端会更新本地 key_storage,心跳任务中会定时调用本接口以应对服务端密钥轮换。调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | get_client_configs |
| HTTP | GET /api/v1/config/client |
| 明文/密文 | 明文 |
| 是否需要登录 | 否 |
响应 data
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | sync_hmac_key |
| HTTP | POST /api/v1/keys/hmac |
| 明文/密文 | 明文(请求体为 username、machine_code) |
| 是否需要登录 | 否(校验用户名+机器码) |
请求体
{
"username": "xxx",
"machine_code": "xxx"
}
响应
常见错误
| code | msg 说明 |
|---|---|
| 401 | 用户不存在/密码错误 |
| 403 | 账号被禁用/机器码不匹配 |
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | get_steam_accounts |
| HTTP | GET /api/v1/steam/accounts(具体以后端路由为准) |
| 明文/密文 | 待确认 |
| 是否需要登录 | 是(需传 user_id 或 session) |
请求
响应 data
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | create_steam_account |
| HTTP | POST /api/v1/steam/accounts |
| 明文/密文 | 待确认 |
| 是否需要登录 | 是 |
请求体(示例,以实际为准)
steam_username、shared_secret、identity_secret、steam_id 等。调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | update_steam_account |
| HTTP | PUT /api/v1/steam/accounts |
| 明文/密文 | 待确认 |
| 是否需要登录 | 是 |
调试备注
| 项目 | 说明 |
|---|---|
| Tauri 命令 | delete_steam_account |
| HTTP | DELETE /api/v1/steam/accounts |
| 明文/密文 | 待确认 |
| 是否需要登录 | 是 |
调试备注
| 日期 | 版本 | 变更说明 |
|---|---|---|
| 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 配置项 |
使用建议:每完成一个接口的联调,请在本文档中: