# 游铛铛项目开发规范 (.cursorrules) ## 项目概述 - **项目名称**: 游铛铛全栈开发项目 - **技术栈**: Vue.js 3 + FastAPI + MySQL + Redis - **项目目标**: BUFF选品和Steam扫货工具 - **核心理念**: "以用户为中心,智慧取舍为先" ## 开发原则 ### 1. 用户中心原则 - 所有功能开发必须以用户需求为优先 - 界面设计要简洁直观,降低学习成本 - 性能优化要确保用户体验流畅 ### 2. 质量优先原则 - 代码必须经过严格的代码审查 - 功能开发完成后必须进行充分测试 - 安全漏洞检查必须通过所有扫描 ### 3. 协作共赢原则 - 团队成员要积极沟通,及时反馈问题 - 跨部门协作要相互尊重,相互支持 - 知识分享要及时,经验传承要完整 ### 4. 持续改进原则 - 定期回顾项目进展,总结经验教训 - 技术选型要考虑长期维护成本 - 流程优化要持续进行,提升效率 ### 5. 配置管理原则 - **客户端配置数据库化**: 所有客户端配置项必须存储在数据库中,不允许硬编码 - **心跳实时同步**: 客户端通过心跳机制实时获取最新配置,无需重启应用 - **动态配置生效**: 配置变更通过数据库修改,秒级生效,提升系统灵活性 - **配置版本管理**: 重要配置变更要有历史记录和回滚机制 ## 代码规范 ### 前端开发规范 (Vue.js) #### 文件命名 - 组件文件: PascalCase (e.g., `UserProfile.vue`) - 工具函数: camelCase (e.g., `formatPrice.js`) - 样式文件: kebab-case (e.g., `user-profile.scss`) - 测试文件: 与源文件同名 + `.spec.js` #### 组件结构 ```vue ``` #### 代码风格 - 使用 ESLint + Prettier 进行代码检查 - 使用 TypeScript 进行类型检查 - 组件名必须有意义,避免缩写 - 变量名使用 camelCase,常量使用 UPPER_SNAKE_CASE #### 状态管理 - 小型组件使用 props + emit - 复杂状态使用 Pinia 进行管理 - 异步操作使用 async/await 语法 #### 配置管理 - **禁止硬编码配置**: 所有客户端配置必须从数据库获取,不允许在代码中写死 - **心跳同步机制**: 通过心跳API实时同步最新配置,支持热更新 - **配置初始化**: 应用启动时通过专用API获取初始配置 - **配置缓存**: 本地缓存配置数据,提升用户体验,但以服务器配置为准 ### 后端开发规范 (FastAPI) #### 项目结构 ``` backend/ ├── app/ │ ├── api/ # API路由 │ ├── core/ # 核心配置 │ ├── models/ # 数据模型 │ ├── schemas/ # 数据验证 │ ├── services/ # 业务逻辑 │ ├── utils/ # 工具函数 │ └── middleware/ # 中间件 ├── tests/ # 测试文件 ├── requirements.txt # 依赖管理 └── main.py # 应用入口 ``` #### API设计规范 - RESTful API 设计原则 - 统一响应格式 - 错误处理规范化 - API 版本控制 - **路由前缀规范**: - **管理端接口**: 所有管理端接口必须以 `/admin/` 开头 - **客户端接口**: 所有客户端接口必须以 `/api/` 开头 - **接口隔离**: 管理端和客户端接口严格分离,不得相互复用 - **配置同步机制**: 心跳API必须包含客户端配置同步功能 - **实时配置更新**: 支持通过API实时推送配置变更 #### 统一用户友好错误提示规范 为保证对用户的友好性与统一体验,所有接口必须遵循以下错误提示规范: - **目标**:对外返回简洁、明确、可执行的用户提示信息;在后台记录完整异常堆栈以便排查,不将内部实现细节暴露给用户。 - **HTTP 状态码使用**: - 200/201:正常响应 - 400:请求参数/请求格式错误(提示:`请求参数错误,请检查后重试`或更具体的信息) - 401:认证失败(提示:`用户名或密码错误` 或 `会话验证失败`) - 403:权限/业务拒绝(提示:`卡密已过期`、`账号已被禁用`、`机器码不匹配` 等明确业务信息) - 404:资源不存在(提示:`资源未找到`) - 5xx:服务端异常(对用户提示友好通用信息,例:`系统异常,请稍后重试;若持续发生请联系客服`) - **返回结构**:使用统一响应函数(如 `create_client_response`)返回结构化 JSON: - 必须包含:`code`(业务码),`msg`(面向用户的提示),`data`(可选) - 业务码建议与 HTTP 状态码语义一致或在文档中明确映射关系。 - **业务错误示例与建议提示**(必须可被前端直接展示): - 用户名或密码错误:`用户名或密码错误,请检查后重试。` - 卡密已过期:`您的卡密已到期,请前往续费或联系客户支持。` - 机器码不匹配:`该账号已绑定其他设备。如需切换设备请先解绑或联系客服。` - 账号被禁用:`账号已被禁用,请联系管理员或客服。` - 会话已过期:`会话已过期,请重新登录。` - 系统/服务器异常(500):`系统异常,操作未完成,请稍后重试;若持续发生请联系客服。` - **实现与日志规范**: - 在捕获未知异常时务必调用 `db.rollback()`(如涉及数据库事务),并使用 `logger.exception(...)` 记录完整堆栈(便于排查)。 - 对外返回信息不得包含异常堆栈、数据库错误或内部路径等敏感信息。 - 对于可预期的业务错误(如卡密过期、机器码不匹配等)应在业务逻辑中明确判断并返回对应的业务提示,而非抛出未捕获异常。 - **前端映射建议**: - 前端应根据 `code` 或 HTTP 状态码映射到具体的用户提示并提供可执行操作(例如“去登录”、“续费”、“联系客服”)。 - 对 5xx 错误展示统一友好页或弹窗,并附带可复制的错误时间/账号信息以便用户反馈给客服。 - **代码审查与验收规则**: - 所有 Pull Request 必须检查新/改接口是否遵循此错误提示规范。 - 自动化测试需覆盖常见错误场景(认证失败、过期、权限拒绝、参数错误、服务异常)。 - 若接口返回 5xx,在合并前需确认日志中能定位到完整异常堆栈。 该规范自提交之日起生效,后续所有接口开发、修改和审查必须参考执行,确保用户始终获得清晰、可执行的错误提示。 #### 数据库规范 - 使用 SQLAlchemy ORM - 表名使用复数形式 - 字段命名使用 snake_case - 必须添加合适的索引 - **配置表设计**: 使用纵表设计存储系统配置,支持动态配置管理 - **配置类型支持**: 支持int/string/bool/json等多种配置值类型 #### 安全规范 - 密码使用 bcrypt 加密 - JWT Token 认证 - 输入验证和清理 - SQL注入防护 ## 项目管理规范 ### 开发流程 1. **需求分析** - 深入理解用户需求 2. **设计评审** - 确认技术方案和UI设计,包括配置项设计 3. **开发实现** - 分阶段完成功能开发,所有配置项存储在数据库中 4. **配置管理** - 建立配置项管理机制,确保可动态调整 5. **测试验证** - 全面测试确保质量,包括配置变更的测试 6. **部署上线** - 安全稳定地发布产品,支持运行时配置更新 ## 📚 项目文档管理系统 ### 核心理念 **"文档是项目发展的基石,有序的文档管理是高效协作的保障"** ### 基本原则 - **文档即代码**: 文档版本与代码版本同步管理 - **分类清晰**: 按职能、类型、阶段进行多维度分类 - **查找便捷**: 让团队成员能在30秒内找到所需文档 - **版本可追溯**: 支持历史版本查询和问题定位 - **协作规范**: 明确文档的创建、维护、审核流程 --- ### 📁 文档组织架构 #### 顶级目录结构 ```bash 项目文档归档/ # 项目根文档目录 ├── 📋 README.md # 项目文档导航页 ├── 🔍 文档索引/ # 文档检索和索引 │ ├── 文档目录.md # 完整文档目录树 │ ├── 搜索指南.md # 文档查找指南 │ └── 更新日志.md # 文档更新历史 ├── 👥 数字员工文档/ # 按职能分类的核心文档 │ ├── 📊 项目经理数字员工/ # 项目管理文档 │ ├── 🎯 需求数字员工/ # 需求分析文档 │ ├── 🎨 设计数字员工/ # UI/UX设计文档 │ ├── 🔧 技术数字员工/ # 技术实现文档 │ └── 🧪 部署测试数字员工/ # 测试和部署文档 ├── 📝 会议记录/ # 项目会议纪要 ├── 🔬 技术方案文档/ # 技术方案评估和决策 ├── 📊 项目报告/ # 项目进度和成果报告 ├── ⚙️ 项目管理文档/ # 项目管理规范和流程 └── 🗂️ 归档文档/ # 历史版本归档 ├── v1.0/ # 按版本号归档 ├── v2.0/ └── legacy/ # 废弃文档 ``` #### 职能目录详细结构 ##### 🔧 技术数字员工目录 ```bash 技术数字员工/ ├── 📊 数据库设计/ # 数据库相关 │ ├── buff.sql # 最新数据库结构 │ ├── migrations/ # 数据库迁移脚本 │ └── design/ # 设计说明文档 ├── 🔌 API文档/ # 接口相关 │ ├── backend-api-v1.0.md # 后端API文档 │ ├── client-api.md # 客户端API │ └── websocket/ # WebSocket接口 ├── 🏗️ 架构设计/ # 系统架构 │ ├── system-architecture.md # 系统架构图 │ ├── deployment-architecture.md # 部署架构 │ └── security-architecture.md # 安全架构 ├── 📦 部署指南/ # 部署相关 │ ├── update-deployment-guide.md # 更新部署 │ ├── version-management-guide.md # 版本管理 │ └── ci-cd-pipeline.md # CI/CD流程 └── 💡 技术方案/ # 技术决策 ├── technology-stack.md # 技术栈选择 ├── framework-analysis.md # 框架分析 └── performance-optimization.md # 性能优化 ``` ##### 🎯 需求数字员工目录 ```bash 需求数字员工/ ├── 📋 需求规格说明书/ # BRD/PRD ├── 🔍 需求分析报告/ # 需求分析 ├── ✅ 验收标准/ # 验收条件 └── 📈 需求变更记录/ # 变更历史 ``` ##### 🎨 设计数字员工目录 ```bash 设计数字员工/ ├── 🎭 UI设计/ # 界面设计 ├── 🔄 交互设计/ # 用户流程 ├── 📱 原型图/ # 原型设计 └── 🎨 设计规范/ # 设计规范 ``` --- ### 🏷️ 文档命名和版本规范 #### 文档命名规范 ```bash # 格式: [日期]-[模块名]-[功能名]-[文档类型]-v[版本].md # 示例: 20240101-user-authentication-api-v1.0.md # API文档 20240101-client-update-deployment-guide-v2.0.md # 部署指南 20240101-database-migration-script-v1.1.sql # 数据库脚本 20240101-system-architecture-design-v3.0.md # 架构设计 ``` #### 版本号规则 - **主版本**: 重大功能变更或架构调整 (x.0.0) - **次版本**: 新功能添加 (x.y.0) - **补丁版本**: bug修复和优化 (x.y.z) - **预发布**: alpha/beta/rc后缀 #### 文档状态标识 ```markdown --- 标题: 用户认证API文档 版本: v1.0.1 状态: ✅ 正式发布 (草稿/审核中/正式发布/已归档) 最后更新: 2024-01-01 更新人: 技术数字员工 审核人: 项目经理数字员工 --- ## 📝 变更历史 - **v1.0.1** (2024-01-01): 修复登录接口文档错误 - **v1.0.0** (2023-12-15): 初始版本发布 ``` --- ### 🔍 文档检索和导航系统 #### 快速查找指南 ```bash # 1. 通过README导航 项目文档归档/README.md # 文档导航主页 # 2. 通过索引查找 项目文档归档/文档索引/文档目录.md # 完整目录树 项目文档归档/文档索引/搜索指南.md # 搜索指南 # 3. 按职能查找 技术实现 → 数字员工文档/技术数字员工/ 需求分析 → 数字员工文档/需求数字员工/ 设计文档 → 数字员工文档/设计数字员工/ # 4. 按类型查找 API文档 → 技术数字员工/API文档/ 数据库 → 技术数字员工/数据库设计/ 部署指南 → 技术数字员工/部署指南/ ``` #### 文档导航主页 (README.md) ```markdown # 📚 游铛铛项目文档中心 ## 🚀 快速开始 - [新人入职指南](./项目管理文档/新人入职指南.md) - [开发环境搭建](./技术数字员工/部署指南/开发环境搭建.md) - [项目架构概览](./技术数字员工/架构设计/system-architecture.md) ## 📖 核心文档 ### 开发相关 - [API文档](./技术数字员工/API文档/backend-api-v1.0.md) - [数据库设计](./技术数字员工/数据库设计/buff.sql) - [部署指南](./技术数字员工/部署指南/) ### 管理相关 - [项目计划](./项目经理数字员工/项目计划.md) - [需求规格](./需求数字员工/需求规格说明书.md) - [设计规范](./设计数字员工/设计规范/) ## 🔍 文档搜索 - [文档目录](./文档索引/文档目录.md) - [搜索指南](./文档索引/搜索指南.md) - [更新日志](./文档索引/更新日志.md) ## 📞 联系方式 - 项目经理: @项目经理数字员工 - 技术负责人: @技术数字员工 - 需求负责人: @需求数字员工 ``` --- ### 🔄 文档生命周期管理 #### 文档创建流程 ```mermaid graph TD A[需求提出] --> B[文档规划] B --> C[文档编写] C --> D[内部审核] D --> E[技术审核] E --> F[正式发布] F --> G[文档归档] ``` #### 文档维护流程 ```mermaid graph TD A[发现问题/需求变更] --> B[评估影响范围] B --> C[制定更新计划] C --> D[文档更新] D --> E[版本标记] E --> F[审核发布] F --> G[通知相关人员] G --> H[更新索引] ``` #### 文档版本管理 ```bash # 文档版本与代码版本同步 ├── v1.0/ # 对应代码v1.0版本 │ ├── api-docs-v1.0.md # API文档v1.0 │ ├── database-v1.0.sql # 数据库v1.0 │ └── architecture-v1.0.md # 架构文档v1.0 ├── v1.1/ # 对应代码v1.1版本 └── v2.0/ # 对应代码v2.0版本 ``` --- ### 📊 文档质量控制 #### 文档质量标准 - **完整性**: 包含所有必要信息,无缺失 - **准确性**: 技术细节准确,数据可靠 - **及时性**: 文档与代码同步更新 - **可读性**: 结构清晰,语言简洁 - **可维护性**: 易于更新和修改 #### 文档审查清单 ```markdown ## 📋 技术文档审查清单 - [ ] 文档结构完整(标题、目录、参考资料) - [ ] 技术内容准确(代码示例可运行,数据正确) - [ ] 格式规范统一(命名、排版、链接) - [ ] 版本信息完整(版本号、更新时间、责任人) - [ ] 关联文档链接正确 - [ ] 敏感信息已脱敏 - [ ] 文档可独立理解(不依赖外部知识) ``` #### 文档更新频率要求 - **架构文档**: 重大变更时更新 - **API文档**: 每次接口变更时更新 - **部署文档**: 部署流程变更时更新 - **用户手册**: 新功能发布时更新 - **故障排查**: 发现新问题时更新 --- ### 🤝 文档协作规范 #### 文档编写规范 ```markdown # 1. 文档头部信息(必需) --- 标题: [文档标题] 版本: v1.0.0 状态: ✅ 正式发布 最后更新: 2024-01-01 编写人: [责任人] 审核人: [审核人] 标签: [技术栈,功能模块] --- # 2. 文档结构(推荐) ## 概述 ## 背景 ## 详细设计 ## 实现方案 ## 测试验证 ## 参考资料 # 3. 代码示例规范 ```bash # 好的示例 npm run build # 带说明的示例 # 构建生产版本 npm run build -- --mode production ``` # 4. 链接规范 - 内部链接: [API文档](../API文档/backend-api.md) - 外部链接: [Vue.js官网](https://vuejs.org/) - 锚点链接: [数据库设计](#数据库设计) ``` #### 文档协作流程 1. **创建**: 在对应目录创建新文档,按命名规范命名 2. **编写**: 使用标准Markdown格式,包含必要元信息 3. **自查**: 使用审查清单进行自查 4. **提交**: 提交到Git,按规范填写commit信息 5. **审核**: 相关人员审核,技术文档由技术负责人审核 6. **发布**: 审核通过后正式发布,更新文档索引 7. **通知**: 在团队群通知文档更新 #### Git提交规范 ```bash # 文档提交格式 docs: add user authentication api docs v1.0 docs: update deployment guide for v2.1 release docs: fix api documentation errors docs: archive outdated design documents ``` --- ### 📈 文档管理监控 #### 文档健康度指标 - **文档覆盖率**: 功能点文档覆盖百分比 - **文档时效性**: 文档更新频率和时效性 - **文档质量**: 通过审查清单的得分 - **文档使用率**: 文档访问和引用频率 #### 定期审查机制 - **周审查**: 检查新增文档质量 - **月审查**: 评估文档组织结构 - **季审查**: 优化文档管理系统 - **年审查**: 全面梳理和归档 #### 文档维护工具 ```bash # 文档质量检查脚本 ./scripts/check-docs-quality.sh # 文档链接检查脚本 ./scripts/check-docs-links.sh # 文档更新提醒脚本 ./scripts/remind-doc-updates.sh ``` --- ### 🎯 文档查找效率目标 #### 响应时间目标 - **紧急问题**: 30秒内找到相关文档 - **一般问题**: 2分钟内定位解决方案 - **学习需求**: 10分钟内掌握相关知识 #### 文档组织原则 1. **预判需求**: 根据常见问题组织文档结构 2. **关联引导**: 相关文档间建立清晰的关联 3. **搜索友好**: 使用标准命名和标签系统 4. **版本清晰**: 明确标识文档版本和状态 --- ### 🚨 文档安全管理 #### 访问权限控制 - **公开文档**: 项目基本信息,对外公开 - **内部文档**: 技术实现细节,仅团队内部 - **敏感文档**: 商业机密、用户数据,限制访问 #### 文档加密保护 ```bash # 敏感文档加密存储 ansible-vault encrypt sensitive-docs/ # 访问时需要密码解密 ansible-vault decrypt sensitive-docs/ ``` #### 文档水印和追踪 - 内部文档添加水印标识 - 记录文档访问日志 - 防止敏感信息泄露 --- **文档管理系统是项目成功的关键保障。通过完善的组织架构、严格的质量控制和高效的检索系统,我们确保团队能够快速找到所需信息,提高协作效率,为项目的长期发展奠定坚实基础。** 📚✨ ### 版本控制 - 使用 Git 进行版本控制 - 分支策略: main(主分支), develop(开发分支), feature/*(功能分支) - 提交信息要清晰明了 - 代码审查后才能合并到主分支 ## 质量保障 ### 测试要求 - 单元测试覆盖率 > 80% - API 接口要有集成测试 - 用户界面要有端到端测试 - 性能测试要达到预期指标 ### 代码审查 - 所有代码都要经过同行审查 - 审查重点: 功能正确性、代码质量、安全性 - 审查意见要及时处理和反馈 - 重大问题必须修复后才能通过 ### 安全检查 - 使用安全扫描工具检查代码 - 定期更新依赖包版本 - 数据库查询要防止SQL注入 - 用户输入要进行严格验证 ## 性能优化 ### 前端性能 - 组件懒加载 - 图片优化和压缩 - 打包体积控制 - 缓存策略优化 ### 后端性能 - 数据库查询优化 - 缓存使用 (Redis) - 异步处理 - 负载均衡 ### 系统性能 - 响应时间 < 300ms - 并发处理 > 800 req/s - 系统可用性 > 99.5% - 资源使用率合理 ## 部署规范 ### 环境管理 - 开发环境: 用于日常开发 - 测试环境: 用于功能测试 - 生产环境: 用于正式上线 ### 容器化部署 - 使用 Docker 进行容器化 - Kubernetes 进行编排管理 - CI/CD 流水线自动化部署 ### 监控告警 - 应用性能监控 - 错误日志收集 - 资源使用监控 - 及时告警处理 ## 团队协作 ### 沟通规范 - 每日站会: 15分钟进度同步 - 问题及时上报,不拖延 - 技术方案讨论要充分 - 跨部门协作要相互尊重 ### 知识分享 - 新技术学习成果分享 - 项目经验教训总结 - 最佳实践文档化 - 培训资料定期更新 ### 责任分工 - 各司其职,各负其责 - 主动承担超出职责范围的工作 - 团队利益高于个人利益 - 相互支持,共同进步 ## 工具使用规范 ### 开发工具 - IDE: 统一使用 VS Code - 版本控制: Git + GitHub - 项目管理: 内部协作平台 - 文档管理: Markdown + 项目文档归档 ### 代码质量工具 - ESLint: JavaScript/TypeScript 代码检查 - Black: Python 代码格式化 - Pre-commit: 提交前检查 - SonarQube: 代码质量分析 ## 异常处理 ### 问题等级 - P0 (紧急): 影响系统正常运行 - P1 (重要): 影响用户使用体验 - P2 (一般): 不影响核心功能 - P3 (低优): 优化和改进建议 ### 处理流程 1. 问题发现和记录 2. 问题分析和定位 3. 解决方案制定 4. 解决方案实施 5. 验证和回归测试 ## 持续改进 ### 回顾机制 - 每周项目进度回顾 - 每月技术方案评估 - 每季度项目目标复盘 - 每年技术栈升级规划 ### 度量指标 - 代码质量指标 - 项目进度指标 - 用户满意度指标 - 团队效率指标 ### 优化方向 - 开发流程优化 - 技术选型优化 - 团队协作优化 - 用户体验优化 --- --- ## 🔐 安全通信规范 (Security Communication Standard) ### 概述 为保证客户端与服务端通信的安全性,所有敏感数据的传输必须使用AES+RSA混合加密方案。本规范以公告获取接口为例,定义了完整的加密通信流程,作为项目标准通信模式。 ### 🎯 核心安全特性 - **AES加密传输**:数据使用AES-256-CBC加密 - **RSA密钥交换**:AES密钥通过RSA公钥加密传输 - **时间戳验证**:防止重放攻击(±5分钟容忍范围) - **HMAC签名**:保证数据完整性 - **Nonce验证**:确保请求唯一性 --- ### 📋 前端安全通信写法 (Frontend Security Communication) #### 1. 公钥状态检查 ```typescript // 检查本地是否有RSA公钥 const hasStoredKey = PublicKeyManager.hasStoredKey() if (!hasStoredKey) { // 显示"系统初始化中"提示 showLoginStatus('系统初始化中,请稍等几分钟...', 'info', 0) return } ``` #### 2. 调用安全的Tauri命令 ```typescript // 🔐 安全优势:所有敏感操作都在Rust原生代码中完成 // 前端只负责UI和简单的数据传递,加密解密在安全的原生环境中进行 const requestData = { page: 1, page_size: 10, keyword: null } const result = await invoke('secure_get_announcements', requestData) // 直接获取解密后的数据 console.log('公告数据:', result.data) ``` #### 3. 安全架构优势 ```typescript // ❌ 旧架构:前端直接处理加密(不安全) const encryptedData = await CryptoUtils.aesEncrypt(data, key, iv) // 前端代码可被逆向 // ✅ 新架构:Rust后端处理所有加密 const result = await invoke('secure_api_call', params) // 原生代码不可逆向 ``` --- ### 🔧 后端安全API写法 (Backend Security API) #### 1. Rust安全API实现 ```rust #[derive(serde::Serialize, serde::Deserialize)] pub struct AnnouncementRequest { pub page: i32, pub page_size: i32, pub keyword: Option, } #[derive(serde::Serialize, serde::Deserialize)] pub struct AnnouncementResponse { pub data: Vec, pub total: i32, pub page: i32, pub page_size: i32, } #[tauri::command] pub async fn secure_get_announcements(request: AnnouncementRequest) -> Result { use base64::{Engine as _, engine::general_purpose}; use serde_json; use reqwest::Client; use std::time::{SystemTime, UNIX_EPOCH}; // 🔐 所有敏感操作都在Rust原生代码中完成: // 1. 获取RSA公钥(从安全存储) let public_key_pem = get_stored_public_key()?; // 从安全存储获取 // 2. 生成随机AES密钥 let aes_key = (0..32).map(|_| rand::random::()).collect::>(); // 3. AES加密请求参数 let request_data = serde_json::json!({ "page": request.page, "page_size": request.page_size, "keyword": request.keyword }); let request_json = request_data.to_string(); let encrypted_params = aes_encrypt(&request_json.as_bytes(), &aes_key)?; let encrypted_params_base64 = general_purpose::STANDARD.encode(&encrypted_params); // 4. RSA加密AES密钥 let encrypted_aes_key = rsa_encrypt_aes_key(&aes_key, &public_key_pem)?; let encrypted_aes_key_base64 = general_purpose::STANDARD.encode(&encrypted_aes_key); // 5. 生成时间戳和nonce let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64; let nonce: String = (0..32).map(|_| format!("{:02x}", rand::random::())).collect(); // 6. 生成签名 let signature_data = format!("{}:{}:{}:{}:{}", timestamp, nonce, encrypted_params_base64, encrypted_aes_key_base64, 1); let signature = generate_hmac_signature(&signature_data)?; // 7. 发送HTTP请求到后端API let client = Client::new(); let api_url = get_api_base_url() + "/api/announcement"; let request_body = serde_json::json!({ "encrypted_params": encrypted_params_base64, "aes_key": encrypted_aes_key_base64, "key_version": 1, "timestamp": timestamp, "nonce": nonce, "signature": signature }); let response = client.post(&api_url).json(&request_body).send().await?; let response_json: serde_json::Value = response.json().await?; // 8. 解密响应数据 if let Some(encrypted_data) = response_json.get("encrypted_data").and_then(|d| d.as_str()) { let encrypted_bytes = general_purpose::STANDARD.decode(encrypted_data)?; let decrypted_data = aes_decrypt(&encrypted_bytes, &aes_key)?; let response_data: serde_json::Value = serde_json::from_slice(&decrypted_data)?; // 提取公告数据 let data = response_data.get("data").unwrap_or(&serde_json::json!([])); let total = response_data.get("total").unwrap_or(&serde_json::json!(0)); let page = response_data.get("page").unwrap_or(&serde_json::json!(1)); let page_size = response_data.get("page_size").unwrap_or(&serde_json::json!(10)); Ok(AnnouncementResponse { data: serde_json::from_value(data.clone())?, total: total.as_i64().unwrap_or(0) as i32, page: page.as_i64().unwrap_or(1) as i32, page_size: page_size.as_i64().unwrap_or(10) as i32, }) } else { Err("No encrypted_data in response".to_string()) } } ``` #### 2. 安全架构优势对比 | 方面 | Rust后端处理 | 前端直接处理 | |------|-------------|-------------| | **代码安全性** | ✅ 原生编译,无法逆向 | ❌ JavaScript可被分析 | | **密钥管理** | ✅ 内存中生成和使用 | ❌ 可能在调试器中暴露 | | **算法隐藏** | ✅ 二进制级别隐藏 | ❌ 源码级别暴露 | | **反调试** | ✅ 原生代码保护 | ❌ 可被浏览器调试 | | **性能** | ✅ 原生加密性能 | ⚠️ JavaScript性能 | | **维护性** | ✅ 集中管理 | ❌ 分散在各组件 | ```rust // ✅ 安全:加密逻辑在原生Rust代码中 // - AES加密/解密不在前端暴露 // - RSA密钥处理在原生环境 // - 签名生成不在前端代码中 // - 攻击者无法通过前端逆向分析 // ❌ 不安全:前端直接处理加密(之前的做法) // const encrypted = await CryptoUtils.aesEncrypt(data, key, iv) // 所有加密算法都暴露在前端JavaScript中 ``` ### 用户认证接口安全调用 #### 1. 安全登录 ```typescript // 检查公钥状态 const hasStoredKey = PublicKeyManager.hasStoredKey() if (!hasStoredKey) { showLoginStatus('系统初始化中,请稍等几分钟...', 'info', 0) return } // 调用安全登录 const requestData = { username: loginForm.username, password: loginForm.password, machine_code: machineCode.value } const userInfo = await invoke('secure_user_login', requestData) // 返回解密后的用户信息 ``` #### 2. 安全注册 ```typescript const requestData = { username: registerForm.username, password: registerForm.password, email: registerForm.email, card_code: registerForm.cardCode } const registerResult = await invoke('secure_user_register', requestData) // 返回注册结果 ``` #### 3. 安全解绑 ```typescript const requestData = { username: unbindForm.username, password: unbindForm.password } const unbindResult = await invoke('secure_user_unbind', requestData) // 返回解绑结果 ``` #### 4. 安全充值 ```typescript const requestData = { username: rechargeForm.username, password: rechargeForm.password, card_code: rechargeForm.cardCode } const rechargeResult = await invoke('secure_user_recharge', requestData) // 返回充值结果 ``` ### 📋 完整安全通信模式开发规范 #### 🔐 安全通信模式概述 游铛铛项目采用 **AES+RSA混合加密** 的企业级安全通信方案,确保所有敏感数据传输的安全性: 1. **前端Vue组件**:负责UI交互和参数收集,只传递必要数据 2. **Rust后端命令**:负责所有加密解密操作,算法不暴露给前端 3. **RSA公钥存储**:RSA公钥采用分段混淆存储在Rust后端内存中,不暴露给前端 4. **传输安全**:AES-256加密数据,RSA-2048加密AES密钥 5. **完整性验证**:HMAC-SHA256签名 + 时间戳 + Nonce验证 --- #### 🛠️ Rust安全命令实现模板 ##### 数据结构定义 ```rust // 请求数据结构 #[derive(serde::Serialize, serde::Deserialize)] pub struct SecureRequest { pub field1: String, pub field2: i32, // ... 业务字段 } // 响应数据结构 #[derive(serde::Serialize, serde::Deserialize)] pub struct SecureResponse { pub code: i32, pub message: String, pub data: Option, } ``` ##### 安全命令模板 ```rust #[tauri::command] pub async fn secure_business_api(request: SecureRequest) -> Result { use base64::{Engine as _, engine::general_purpose}; use serde_json; use reqwest::Client; use std::time::{SystemTime, UNIX_EPOCH}; // 🔐 安全通信流程: // 1. 获取RSA公钥(从安全存储) let public_key_pem = get_stored_public_key()?; // 从安全存储获取 // 2. 生成随机AES密钥 (32字节) let aes_key = (0..32).map(|_| rand::random::()).collect::>(); // 3. AES加密请求参数 let request_data = serde_json::json!({ "field1": request.field1, "field2": request.field2 // 业务参数 }); let request_json = request_data.to_string(); let encrypted_params = aes_encrypt(&request_json.as_bytes(), &aes_key)?; let encrypted_params_base64 = general_purpose::STANDARD.encode(&encrypted_params); // 4. RSA加密AES密钥 let public_key_parsed = RsaPublicKey::from_public_key_pem(public_key_pem) .map_err(|e| format!("Failed to parse public key: {}", e))?; let mut rng = OsRng; let encrypted_aes_key = public_key_parsed.encrypt(&mut rng, Pkcs1v15Encrypt, &aes_key) .map_err(|e| format!("Failed to encrypt AES key: {}", e))?; let encrypted_aes_key_base64 = general_purpose::STANDARD.encode(&encrypted_aes_key); // 5. 生成时间戳和nonce let timestamp = SystemTime::now() .duration_since(UNIX_EPOCH) .map_err(|e| format!("Time error: {}", e))? .as_secs() as i64; let nonce: String = (0..32).map(|_| format!("{:02x}", rand::random::())).collect(); // 6. 生成HMAC签名 let signature_data = format!("{}:{}:{}:{}:{}", timestamp, nonce, encrypted_params_base64, encrypted_aes_key_base64, key_version); type HmacSha256 = Hmac; let mut mac = HmacSha256::new_from_slice(b"buff-client-secret-2024") .map_err(|e| format!("HMAC init failed: {}", e))?; mac.update(signature_data.as_bytes()); let signature_bytes = mac.finalize().into_bytes(); let signature = general_purpose::STANDARD.encode(&signature_bytes); // 7. 发送HTTP请求 let client = Client::new(); let api_url = format!("{}/api/business_endpoint", base_url); let request_body = serde_json::json!({ "encrypted_params": encrypted_params_base64, "aes_key": encrypted_aes_key_base64, "key_version": key_version, "timestamp": timestamp, "nonce": nonce, "signature": signature }); let response = client.post(api_url).json(&request_body).send().await?; let response_json: serde_json::Value = response.json().await?; // 8. 验证响应并解密 if let Some(code) = response_json.get("code") { if code != 200 { let msg = response_json.get("msg").and_then(|m| m.as_str()).unwrap_or("API error"); return Err(format!("API error: {}", msg)); } } if let Some(encrypted_data) = response_json.get("encrypted_data").and_then(|d| d.as_str()) { let encrypted_bytes = general_purpose::STANDARD.decode(encrypted_data)?; let decrypted_data = aes_decrypt(&encrypted_bytes, &aes_key)?; let business_data: BusinessData = serde_json::from_slice(&decrypted_data)?; Ok(SecureResponse { code: 200, message: "Success".to_string(), data: Some(business_data), }) } else { Err("No encrypted_data in response".to_string()) } } ``` --- #### 🎨 Vue组件调用模板 ##### 导入依赖 ```typescript import { invoke } from '@tauri-apps/api/tauri' import { PublicKeyManager } from '../utils/PublicKeyManager' // 业务数据类型 interface BusinessRequest { field1: string field2: number } interface BusinessResponse { code: number message: string data?: BusinessData } ``` ##### 安全API调用模板 ```typescript const secureBusinessApi = async (requestData: BusinessRequest): Promise => { // 🔍 1. 检查本地RSA公钥状态 const hasStoredKey = PublicKeyManager.hasStoredKey() if (!hasStoredKey) { console.log('本地RSA公钥不存在,无法进行安全调用') throw new Error('系统初始化中,请稍等几分钟') } // 🔐 2. 调用Rust安全命令 // 所有加密解密都在Rust原生代码中完成,前端不可见 try { const response: BusinessResponse = await invoke('secure_business_api', requestData) // ✅ 3. 返回解密后的业务数据 return response } catch (error: any) { console.error('安全API调用失败:', error) // 🚨 错误处理:根据错误类型提供用户友好的提示 if (!PublicKeyManager.hasStoredKey()) { throw new Error('系统初始化中,请稍等几分钟') } // 业务错误映射 const errorMessage = (() => { const errText = error?.toString() || '' if (errText.includes('网络错误')) return '网络连接失败,请检查网络后重试' if (errText.includes('超时')) return '请求超时,请稍后重试' if (errText.includes('权限')) return '权限不足,无法执行此操作' return errText || '操作失败,请稍后重试' })() throw new Error(errorMessage) } } ``` --- #### 🔧 AES加密解密辅助函数 ```rust // AES加密:数据 + 密钥 → Base64(IV+加密数据) fn aes_encrypt(data: &[u8], key: &[u8]) -> Result, String> { // 生成16字节随机IV let iv: Vec = (0..16).map(|_| rand::random::()).collect(); let mut cipher = Ctr64BE::::new_from_slices(key, &iv) .map_err(|e| format!("AES cipher init failed: {}", e))?; let mut encrypted_data = data.to_vec(); cipher.apply_keystream(&mut encrypted_data); // 返回:IV(16) + 加密数据 let mut result = iv; result.extend_from_slice(&encrypted_data); Ok(result) } // AES解密:Base64(IV+加密数据) + 密钥 → 原始数据 fn aes_decrypt(encrypted_data: &[u8], key: &[u8]) -> Result, String> { if encrypted_data.len() < 16 { return Err("Invalid encrypted data length".to_string()); } // 提取IV和加密数据 let iv = &encrypted_data[0..16]; let encrypted_payload = &encrypted_data[16..]; let mut cipher = Ctr64BE::::new_from_slices(key, iv) .map_err(|e| format!("AES cipher init failed: {}", e))?; let mut decrypted_data = encrypted_payload.to_vec(); cipher.apply_keystream(&mut decrypted_data); Ok(decrypted_data) } ``` --- #### ⚡ 快速实现新安全接口的步骤 ##### Step 1: 定义数据结构 ```rust #[derive(serde::Serialize, serde::Deserialize)] pub struct MyApiRequest { pub param1: String, pub param2: i32, } #[derive(serde::Serialize, serde::Deserialize)] pub struct MyApiResponse { pub result: String, pub data: Option, } ``` ##### Step 2: 实现安全命令 ```rust #[tauri::command] pub async fn secure_my_api(request: MyApiRequest) -> Result { // 复制上面的安全通信模板 // 修改业务参数和API端点 // ... } ``` ##### Step 3: 注册命令 ```rust fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![ // ... 其他命令 secure_my_api, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } ``` ##### Step 4: Vue组件调用 ```typescript const callMyApi = async (params: MyApiRequest) => { // 复制上面的安全调用模板 // 修改参数和命令名 const result = await invoke('secure_my_api', params) return result } ``` --- #### 🎯 安全优势总结 | 方面 | 传统方式 | 安全通信模式 | 提升 | |------|----------|-------------|------| | **算法隐藏** | ❌ 前端可见 | ✅ Rust原生隐藏 | 🚀 极大提升 | | **RSA公钥安全** | ❌ 前端存储 | ✅ Rust后端内存 | 🚀 极大提升 | | **逆向难度** | ⭐⭐ | ⭐⭐⭐⭐⭐ | 🚀 极大提升 | | **传输安全** | ❌ HTTP明文 | ✅ AES-256加密 | 🚀 极大提升 | | **完整性验证** | ❌ 无 | ✅ HMAC+时间戳+Nonce | 🚀 极大提升 | | **中间人攻击** | ❌ 极易 | ✅ 几乎不可能 | 🚀 极大提升 | | **代码可维护性** | ❌ 分散 | ✅ 集中管理 | ✅ 提升 | --- #### 📝 开发注意事项 1. **所有敏感接口必须使用此模式** 2. **RSA公钥存储在Rust后端内存中,前端不可访问** 3. **AES密钥每次请求都必须重新生成** 4. **时间戳容忍范围:±5分钟** 5. **错误信息不能暴露内部实现细节** 6. **前端只负责UI,后端处理所有安全逻辑** 7. **公钥获取后自动存储到Rust后端,无需前端处理** --- ## 🛡️ Rust后端RSA公钥分段混淆存储 ### 存储架构设计 为了进一步提升RSA公钥的安全性,Rust后端实现了分段混淆存储机制: ```rust // 8个分段存储位置(随机顺序) static mut RSA_KEY_SEGMENTS: [Option; 8] = [ None, None, None, None, None, None, None, None ]; // 分段存储的随机索引映射 static RSA_KEY_SEGMENT_ORDER: [usize; 8] = [3, 7, 1, 5, 0, 6, 2, 4]; ``` ### 多层安全防护 #### **1. 数据编码层** ```rust fn encode_rsa_key_data(data: String) -> String { // Base64编码(可逆操作) general_purpose::STANDARD.encode(data) } ``` #### **2. 分段存储层** ```rust fn store_rsa_key_segments(public_key: String) { let encoded_key = encode_rsa_key_data(public_key); // 将编码后的数据分拆到8个随机位置存储 let segment_size = (encoded_key.len() + 7) / 8; let mut start = 0; for &segment_index in RSA_KEY_SEGMENT_ORDER.iter() { let end = std::cmp::min(start + segment_size, encoded_key.len()); let segment = encoded_key[start..end].to_string(); // 为每个段添加固定噪声标记 let noisy_segment = add_noise_to_segment(segment); unsafe { RSA_KEY_SEGMENTS[segment_index] = Some(noisy_segment); } start = end; } } ``` #### **3. 重组验证层** ```rust fn retrieve_rsa_key_segments() -> Result { // 按正确顺序收集所有段 let mut clean_segments = Vec::new(); for &segment_index in RSA_KEY_SEGMENT_ORDER.iter() { if let Some(segment) = unsafe { &RSA_KEY_SEGMENTS[segment_index] } { // 移除噪声标记 let clean_segment = remove_noise_from_segment(segment.clone()); clean_segments.push(clean_segment); } else { return Err("RSA公钥段缺失".to_string()); } } // 重新组合并解码 let combined_data = clean_segments.concat(); decode_rsa_key_data(combined_data) } ``` ### 安全优势对比 | 安全维度 | 简单存储 | 分段混淆存储 | 提升程度 | |----------|----------|-------------|----------| | **内存连续性** | ❌ 连续内存块 | ✅ 8个分散位置 | 🚀 极大提升 | | **数据可读性** | ❌ 明文可见 | ✅ 多重编码混淆 | 🚀 极大提升 | | **逆向分析难度** | ⭐⭐ | ⭐⭐⭐⭐⭐ | 🚀 极大提升 | | **内存转储攻击** | ❌ 容易获取 | ✅ 需要重组算法 | 🚀 极大提升 | | **动态混淆** | ❌ 固定存储 | ✅ 每次重新编码 | 🚀 极大提升 | ### 存储效果示例 假设原始RSA公钥: ``` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... -----END PUBLIC KEY----- ``` 分段混淆存储后的内存分布: ``` 内存位置 0: "8:9KLMNc3VzXyZABC..." 内存位置 1: None (跳过) 内存位置 2: "ab4FgHiJkL8MnOpQr..." 内存位置 3: "hIjKlMnOpQrStUvW..." 内存位置 4: None (跳过) 内存位置 5: "3StUvWxYzAbCdEfG..." 内存位置 6: "ab4FgHiJkL8MnOpQr..." 内存位置 7: "!@#NoiseChars#$%..." ``` ### 安全机制特点 1. **8段分散存储** - RSA公钥被分成8个不连续的内存段 2. **随机存储顺序** - 使用预定义的随机索引映射存储 3. **可逆编码** - Base64编码确保数据完整性 4. **固定噪声标记** - 每个段添加可移除的噪声标记 5. **确定性重组** - 使用固定算法重组恢复数据 6. **完整性验证** - 存储和重组都有错误检测和验证 ### 🎯 设计原则 **可逆性优先于复杂性**:虽然简化了混淆算法,但确保了数据能够100%正确重组,这是安全通信系统的生命线。复杂的不可逆混淆可能增加安全性,但如果导致数据无法正确重组,将会破坏整个安全通信功能。 这种分段混淆存储机制让RSA公钥在Rust后端内存中**极难被逆向工程获取**,即使攻击者能够进行内存转储或调试,也无法轻易恢复出完整的RSA公钥!🔐✨ --- *本规范确保项目所有敏感数据传输的安全性,开发时请严格遵循此模式。* 🔐✨ #### 4. 工具函数 ```python import hmac import hashlib import base64 import json import secrets from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding def _generate_signature(data: str, secret_key: str) -> str: """生成HMAC签名""" signature = hmac.new( secret_key.encode(), data.encode(), hashlib.sha256 ).digest() return base64.b64encode(signature).decode() def _verify_signature(data: str, signature: str, secret_key: str) -> bool: """验证HMAC签名""" try: expected_signature = _generate_signature(data, secret_key) return signature == expected_signature except Exception as e: logger.exception("签名验证异常") return False ``` --- ### 📝 开发规范要求 #### 前端开发要求 1. **必须使用AES+RSA混合加密**:所有敏感数据传输必须使用此方案 2. **随机AES密钥**:每次请求都生成新的随机AES密钥 3. **RSA公钥管理**:通过`/api/keys/public`接口获取并缓存RSA公钥 4. **完整安全验证**:时间戳、nonce、签名缺一不可 5. **错误处理**:公钥不存在时显示友好提示 #### 后端开发要求 1. **安全装饰器**:所有敏感接口必须使用`@secure_endpoint`装饰器 2. **密钥版本验证**:必须验证RSA公钥版本的有效性 3. **时间戳容忍**:默认±5分钟,可根据业务调整 4. **错误响应**:安全错误不泄露系统信息 5. **日志记录**:记录所有安全相关事件 #### 密钥管理要求 1. **RSA密钥轮换**:支持多版本RSA密钥管理 2. **AES密钥单次**:AES密钥只在单次请求中使用 3. **公钥缓存**:RSA公钥可在客户端缓存,但有过期检查 4. **私钥安全**:RSA私钥只在服务端,永不传输 #### 安全监控要求 1. **异常监控**:监控签名验证失败、时间戳异常等安全事件 2. **频率限制**:对敏感接口实施频率限制 3. **审计日志**:记录所有安全相关操作 4. **告警机制**:异常情况及时告警 --- ### 🚨 安全注意事项 1. **不要硬编码密钥**:生产环境使用环境变量或配置管理 2. **时间戳同步**:确保客户端和服务端时间同步 3. **密钥轮换**:定期更换RSA密钥对 4. **传输安全**:虽然数据已加密,仍建议使用HTTPS 5. **内存清理**:请求完成后清理内存中的敏感数据 6. **错误信息**:不要在错误响应中暴露内部实现细节 --- *本规范由项目经理数字员工制定* *最后更新时间: 2026-01-07* *文档管理系统版本: v1.1.0* *配置管理系统版本: v1.0.0* *安全通信规范版本: v1.1.0* *适用范围: 游铛铛项目全团队*