# 游铛铛客户端 exe 前后端实现检查报告 > 依据文档:`docs/客户端exe技术方案.md` (v1.3.0) > 检查范围:client-tauri(前端 + Rust 命令)、backend-client(FastAPI 接口) --- ## 一、总体结论 | 维度 | 符合情况 | 说明 | |--------------|----------|------| | 后端接口覆盖 | ✅ 基本符合 | 认证、心跳、公告、密钥、用户、Steam、HMAC 等路由已实现 | | 客户端命令 | ✅ 基本符合 | 安全登录/注册/解绑/充值、公告、密钥管理、心跳、机器码等已实现 | | 安全通信 | ⚠️ 部分差异 | 心跳/用户信息请求未走 AES+RSA;公钥获取方式与文档不一致 | | 接口日志 4.4 | ⚠️ 部分符合 | 有 ASGI 日志中间件与 api_logs;DB 存的是密文,文档 4.5 要求存明文 | | 前端结构 | ✅ 基本符合 | 有 Login/Home/Settings/Steam 等视图与 auth/config/heartbeat store | --- ## 二、后端 (backend-client) 实现情况 ### 2.1 接口分类与路由(对应文档 4.1、8.2) | 文档要求 | 后端实现 | 状态 | |----------|----------|------| | POST /api/auth/login (AES+RSA) | `@secure_endpoint` POST `/v1/auth/login` | ✅ | | POST /api/auth/register (AES+RSA) | `@secure_endpoint` POST `/v1/auth/register` | ✅ | | POST /api/auth/recharge (AES+RSA) | `@secure_endpoint` POST `/v1/auth/recharge` | ✅ | | POST /api/auth/unbind (AES+RSA) | `@secure_endpoint` POST `/v1/auth/unbind` | ✅ | | POST /api/heartbeat (AES+RSA,需登录) | POST `/v1/heartbeat` 接收**明文** `HeartbeatRequest`,响应用 `create_encrypted_response` | ⚠️ 请求未加密 | | POST /api/user/profile (AES+RSA,需登录) | POST `/v1/user/profile` 接收**明文** `dict`,响应加密 | ⚠️ 请求未加密 | | GET/POST /api/announcements | GET `/v1/announcements` 明文;POST `/v1/announcements` 为 `@secure_endpoint` | ✅ | | POST /api/keys/public (AES) | POST `/v1/keys/public` 已实现(加密响应) | ✅ | | GET /api/keys/public | GET `/v1/keys/public` 明文返回公钥 | ✅ | | POST /api/keys/sync (已登录) | 未单独实现,可与 keys/public 或心跳配合 | ⚠️ 文档有描述,后端无独立 sync 路由 | | POST /api/keys/hmac | POST `/v1/keys/hmac` 动态 HMAC 密钥 | ✅ | | Steam 绑定/解绑/列表 | POST/GET/PUT/DELETE `/v1/steam/accounts` | ✅ | 路由挂载:`app/include_router(api_router, prefix="/api")`,v1 在 `api_router` 下 `prefix="/v1"`,故实际路径为 `/api/v1/...`,与文档中「/api/」表述一致(文档未强制写 v1)。 ### 2.2 安全中间件与签名(文档 3.3、3.4、8.3) - `secure_endpoint`:已实现解密请求、验证签名/时间戳/nonce、会话与机器码校验(需登录时)、`create_encrypted_response` 生成响应签名并加密。 - 双向签名:服务端用 `create_encrypted_response` 生成 `response_signature`;客户端在 `commands.rs` 中有 `verify_response_signature`。 - 动态 HMAC(3.3.1):`/api/v1/keys/hmac`、`hmac_key_service` 已存在。 ### 2.3 接口日志(文档 4.4、4.5) - **APILoggingASGIMiddleware**:已启用,记录请求/响应体、按天滚动、可写 DB。 - **api_logs 表**:模型含 `request_data`、`response_data`、`endpoint`、`method`、`response_code`、`execution_time` 等。 - **差异**:文档 4.5 约定「request_data = 加密前的原始请求参数」「response_data = 解密后的原始响应数据」,即**明文**;当前中间件写入 DB 的是**密文**(截断后的 encrypted_request/encrypted_response)。若严格按 4.5,应写入解密后的明文(或同时保留密文字段)。 ### 2.4 数据库与配置 - 使用 `api_logs`、`users`、`sessions`、`cards`、`system_config`、密钥等模型;配置从 `system_config` 读取,与文档一致。 --- ## 三、客户端 (client-tauri) 实现情况 ### 3.1 Rust 命令与安全调用(文档 7.3、7.4) | 文档/方案要求 | 实现 | 状态 | |---------------|------|------| | 安全登录 | `secure_user_login`,AES+RSA + 响应签名校验 | ✅ | | 安全注册 | `secure_user_register` | ✅ | | 安全解绑 | `secure_user_unbind` | ✅ | | 安全充值 | `secure_user_recharge` | ✅ | | 安全公告 | `secure_get_announcements` | ✅ | | RSA 公钥分段存储 | `store_rsa_key_segments` / `retrieve_rsa_key_segments`、噪声处理 | ✅ | | 密钥管理 | `initialize_key_manager`、`refresh_key_if_needed`、`has_stored_rsa_key`、`get_key_manager_status` 等 | ✅ | | 动态 HMAC | `sync_hmac_key`、`has_valid_hmac_key`、`get_hmac_key_status`、`sync_hmac_key_command` | ✅ | | 机器码 | `get_machine_code`(硬盘序列号+MAC,文档 3.1) | ✅ | | 心跳 | `execute_heartbeat`、`start_heartbeat_service`、`stop_heartbeat_service`、`get_heartbeat_config_command` 等 | ✅ | | 获取用户信息 | `get_user_profile`:**明文** POST `/api/user/profile` | ⚠️ 与文档「AES+RSA」不一致 | ### 3.2 公钥获取(文档 4.3.1、12.1) - **文档**:客户端启动应调用 **POST** `/api/keys/public`,请求体为 AES 加密(含机器特征),响应为加密公钥。 - **当前实现**: - `key_manager.initialize_key_manager` 使用 **GET** `/api/v1/keys/version` 获取版本与公钥(明文)。 - `api_client.get_public_key` 使用 **GET** `/api/v1/keys/public`(明文)。 - 因此与文档「POST + AES 加密获取公钥」的启动流程不一致;若需严格合规,应改为 POST `/api/v1/keys/public` 并走加密请求/响应。 ### 3.3 心跳请求加密(文档 4.2 场景三、4.3.6) - **文档**:心跳请求应为 AES+RSA 加密(如携带 session_id、machine_code)。 - **当前**:`heartbeat.rs` 中 `execute_heartbeat` 使用 **明文 JSON** `{"session_id","machine_code"}` POST 到 `/api/v1/heartbeat`,响应端解析 `encrypted_data` 并解密。 - 结论:**心跳请求未加密**,与方案要求不符;若需一致,应改为与登录等接口相同的安全端点调用方式。 ### 3.4 前端结构(文档 7.2) - **视图**:LoginView、HomeView、SettingsView、SteamBindView、RechargeDialog、RegisterDialog、UnbindDialog 等已存在。 - **Store**:authStore、configStore、heartbeatStore、index。 - 文档中的「MainLayout / Header / Sidebar / AnnouncementList」等为建议结构,当前以视图内嵌或简化形式存在,可视为基本符合。 ### 3.5 单例与进程安全(文档 3.1) - `tauri_plugin_single_instance` 已在 `main.rs` 中使用,符合「已运行则激活窗口并退出当前」的描述。 --- ## 四、差异与建议 ### 4.1 必须/建议对齐项 1. **心跳接口** - 方案:POST /api/heartbeat 请求与响应均为 AES+RSA。 - 现状:后端接收明文 Body,仅响应加密;客户端发明文。 - 建议:后端将 `/v1/heartbeat` 改为 `@secure_endpoint`(或同等解密与签名逻辑);客户端改为与 `secure_user_login` 类似的加密请求 + 响应签名校验。 2. **用户信息接口** - 方案:POST /api/user/profile 需登录且 AES+RSA。 - 现状:后端接收明文 `session_id/machine_code`,仅响应加密;客户端 `get_user_profile` 发明文。 - 建议:后端改为 `@secure_endpoint`,客户端改为安全加密调用(与登录/公告一致)。 3. **RSA 公钥获取(启动流程)** - 方案:启动时 POST /api/keys/public,AES 加密请求与响应。 - 现状:客户端用 GET /keys/version 或 GET /keys/public 明文获取。 - 建议:若需与文档完全一致,客户端启动流程改为调用 POST `/api/v1/keys/public`,并实现请求加密与响应解密(后端 POST 已支持加密响应)。 4. **api_logs 表内容(4.5)** - 方案:request_data = 加密前原始请求参数(明文),response_data = 解密后原始响应数据(明文)。 - 现状:中间件写入的为密文(截断)。 - 建议:在安全端点解密后,将解密后的请求/响应写入 api_logs(或增加 plain_request_data / plain_response_data 字段),并对敏感字段脱敏。 ### 4.2 可选/已基本满足项 - **POST /api/keys/sync**:文档 4.3.2 描述已登录状态下同步公钥;当前可通过 GET /keys/public 或心跳携带配置实现,若需独立接口可再加。 - **接口日志 4.4**:文件日志与 ASGI 中间件已具备;主要差在 DB 存明文与脱敏的明确落地。 - **前端组件拆分**:Header/Sidebar/MainLayout/AnnouncementList 可按后续迭代再细化,不影响当前功能符合性。 --- ## 五、检查清单汇总 | 项目 | 后端 | 客户端 | 备注 | |------|------|--------|------| | 登录/注册/解绑/充值 (AES+RSA) | ✅ | ✅ | 一致 | | 公告 (AES+RSA) | ✅ | ✅ | POST 安全端点 + secure_get_announcements | | 心跳 (AES+RSA) | ⚠️ 仅响应加密 | ⚠️ 请求明文 | 建议请求也加密 | | 用户信息 (AES+RSA) | ⚠️ 仅响应加密 | ⚠️ 请求明文 | 建议改为安全端点 | | RSA 公钥获取 (POST+AES) | ✅ POST 已实现 | ⚠️ 使用 GET 明文 | 启动流程可改为 POST | | 动态 HMAC | ✅ | ✅ | 已实现 | | RSA 分段存储 / 响应签名校验 | - | ✅ | 已实现 | | 机器码 (硬盘+MAC) | - | ✅ | 已实现 | | 单例进程 | - | ✅ | 已实现 | | 接口日志 4.4(文件+控制台) | ✅ | - | 已实现 | | api_logs 4.5(明文+脱敏) | ⚠️ 当前存密文 | - | 建议按文档存明文并脱敏 | --- **报告生成说明**:本报告基于对 `client-tauri/`、`backend-client/` 及 `docs/客户端exe技术方案.md` 的静态阅读与 grep 检索整理,未执行运行时测试。实施上述建议时请在测试环境验证后再上线。