| 维度 | 结论 | 说明 |
|---|---|---|
| 接口是否校验登录 | 是 | 需登录的接口由后端统一校验 session(选品配置/选品开始已改用 verify_session_with_machine_and_expiry) |
| 接口是否校验机器码 | 是 | 心跳、选品配置、选品开始等接口均要求传 machine_code 并与 session 绑定一致,否则 403 |
| 接口是否判断用户过期 | 是 | 上述接口在后端统一校验用户卡密/订阅未过期,过期返回 403 |
| 发生上述情况是否退出登录 | 是 | 客户端对 401/403 统一走 handleAuthError → 退登并跳转登录页 |
| 退出登录是否关闭子进程 | 是 | 登出时已调用 stop_all_processes(),会尝试远程停止选品与扫货任务(selection-stop / sweep-stop),失败仅记录日志不阻断登出 |
authStore.machineCode 来自 Rust get_machine_code()(即 machine::generate_machine_code())。DISK=<硬盘序列号>(例如 DISK=WD-WMAZA1234567)。多盘时取第一个磁盘序列号;不含 MAC,避免换网卡/IP 导致同机不同码。详见 client-tauri/src-tauri/src/machine.rs。raw_machine_info / machine_code,用 raw_machine_info_to_machine_code(raw) 做规范化 + MD5,得到 32 位小写 hex,再与 session.machine_code(登录时存的也是该 MD5)比较。authStore.machineCode = get_machine_code())。verify_session_with_machine_and_expiry 会对入参做统一规范化:
session.machine_code 比较;DISK=xxx),先 raw_machine_info_to_machine_code(mc) 得到 MD5,再与 session.machine_code 比较。这样无论客户端传 raw 还是 MD5,后端都能与登录时绑定的机器码一致校验。
auth_service.login、heartbeat_service.heartbeat。AuthService.verify_session_with_machine_and_expiry(session_id, machine_code):统一校验会话有效 + 机器码与 session 一致 + 用户未禁用 + 用户卡密未过期。POST/GET /buff/selection-config、POST /buff/selection-start,请求体/查询参数均要求传 session_id 与 machine_code。secureApiClient.login:401/403 → handleAuthErrorsecureApiClient.recharge:401/403 → handleAuthErrorsecureApiClient.unbind:401/403 → handleAuthErrorsecureApiClient.changePassword:错误信息含 401/403/会话 → handleAuthErrorsecureApiClient.heartbeat:401/403 或 catch 到会话相关错误 → handleAuthErrorsecureApiClient.getProfile:401/403 → handleAuthErrorsecureApiClient.getBuffSelectionConfig:401/403 → handleAuthErrorsecureApiClient.saveBuffSelectionConfig:401/403 → handleAuthErrorgetAnnouncements:公告接口,未做 401/403 退登(按设计可为公开)。getClientConfigs:后端为“无需登录”的配置接口,未做 401/403 退登。getBuffFilterOptions / getBuffGoodsAttrList:已改为需登录,后端校验 session + machine_code + 用户过期,前端传参并做 401/403 → handleAuthError。syncHmacKey(密钥同步):后端已校验用户+机器码+卡密过期,前端 401/403 → handleAuthError。handleAuthError 会:停止心跳、调用 authStore.logout()、派发 auth-error,由 App.vue 统一 router.replace('/login')。user_logout 顺序为:stop_all_processes()(停止客户端 exe 开启的子进程,如选品、扫货);stop_heartbeat_service();stop_all_processes() 已实现并在登出时被调用,内部会调用后端安全接口停止选品与扫货任务(/api/v1/buff/secure/selection-stop、/api/v1/buff/secure/sweep-stop)。app/services/auth_service.py
verify_session_with_machine_and_expiry(session_id, machine_code, software_code=None):校验会话存在且未过期、请求机器码与 session 一致、用户存在且未禁用、用户卡密未过期;返回 (session, err_code, err_msg),失败时为 401/403。app/api/v1/router.py
POST /buff/selection-config:请求体增加必填 machine_code,改用 verify_session_with_machine_and_expiry,不通过返回 401/403。GET /buff/selection-config:查询参数增加必填 machine_code,同上。POST /buff/selection-start:请求体增加必填 machine_code,同上。src/utils/secureApiClient.ts
getBuffSelectionConfig(session_id, machine_code):增加参数 machine_code,请求 URL 带 machine_code;响应 401/403 时调用 handleAuthError。saveBuffSelectionConfig:参数增加必填 machine_code,请求体带 machine_code;响应 401/403 时调用 handleAuthError(此前已加)。src/views/BuffSelectionView.vue
authStore.machineCode 取值,调用 getBuffSelectionConfig(sessionId, machineCode) 与 saveBuffSelectionConfig(..., machine_code: machineCode)。src-tauri/src/commands.rs
user_logout:在停止心跳之前先调用 stop_all_processes().await(错误仅打日志,不阻断登出),保证登出时尝试关闭子进程。@secure_endpoint(require_login=True, require_machine_code=True) 做会话+机器码+用户状态+用户卡密过期校验,不通过返回 401/403。validate_user_for_hmac 增加用户卡密/订阅过期校验,过期返回 403;前端 syncHmacKey 在 401/403 时调用 handleAuthError 触发退登。session_id、machine_code,使用 verify_session_with_machine_and_expiry 做三项校验;前端传参并在 401/403 时 handleAuthError,选品页调用处传入 authStore.sessionId、authStore.machineCode。文档生成日期:2026-03-01;改造完成:选品相关接口已统一“登录+机器码+过期”校验并触发退登,登出时已调用 stop_all_processes;登录后业务接口(含心跳、密钥交换、选品)均已三项校验且 401/403 退登。