技术架构

深入了解 GEO Wiki Pro 的技术架构,包括前端、后端、存储和安全设计。

## 架构概览 GEO Wiki Pro 采用**前后端分离**架构,前端为单页应用(SPA),后端为 RESTful API 服务。整个系统设计遵循**文件即数据库**的理念,无需传统数据库。 ``` ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ Vue 3 SPA │────▶│ Express.js API │ │ (Vite 5) │ │ (Node.js 22) │ │ │ │ │ └─────────────────┘ └────────┬────────┘ │ ┌────────────┴────────────┐ │ │ ┌─────┴─────┐ ┌───────┴───────┐ │ Markdown │ │ 上传的媒体 │ │ 文件存储 │ │ 文件存储 │ └───────────┘ └───────────────┘ ``` ## 前端架构 ### 技术栈 - **框架**:Vue 3(Composition API) - **构建工具**:Vite 5 - **样式**:Tailwind CSS 3.4 - **状态管理**:Pinia - **路由**:Vue Router 4 - **搜索**:Fuse.js(客户端模糊搜索) ### 目录结构 ``` src/ pages/ # 20 个页面组件,路由映射 components/ # 24 个可复用组件 stores/ # Pinia 状态仓库:docsStore, uiStore, siteConfigStore api/ # API 客户端模块 client.js # 导出 apiClient 对象 request.js # request()(认证)+ requestPublic()(公开) docs.js # 文档 CRUD + 搜索 auth.js # 登录/登出/注册 llm.js # AI 功能 admin.js # 管理后台 API utils/ # 工具函数:i18n.js, markdown.js, icons.js, schema.js i18n/ # 翻译文件:zh.json, en.json, jp.json ``` ### 核心模块 - **docsStore**:管理文档列表、分类、标签的状态和缓存 - **uiStore**:管理 UI 状态(语言、侧边栏、主题等) - **siteConfigStore**:管理站点配置(Hero 区域、Logo、特色文档等) ## 后端架构 ### 技术栈 - **运行时**:Node.js 22 - **框架**:Express.js - **存储**:文件系统(Markdown + JSON) - **认证**:JWT(jsonwebtoken) - **安全**:Helmet(CSP)、express-rate-limit ### 目录结构 ``` server/ index.js # Express 入口,中间件链(固定顺序) db.js # 文件系统数据库核心(读写/队列/缓存) routes/ docs.js # 公开:GET /docs, GET /docs/:slug auth.js # POST /login, POST /logout, GET /me captcha.js # 验证码生成/验证 meta.js # GET /categories, GET /tags geo.js # llms.txt, sitemap.xml, manifest llm.js # AI 内容分析/生成 media.js # 文件上传/下载 config.js # 站点配置 versions.js # 文档版本历史 admin/ # 受保护的管理路由 index.js # 挂载所有管理子路由 docs.js # CRUD + 排序 drafts.js # 草稿审批流程 categories.js, tags.js, feedback.js geo.js, stats.js, crawler-block.js guestbook.js, users.js middleware/ auth.js # JWT 验证、角色检查、密码修改检查 csrf.js # CSRF 保护(Double-Submit Cookie) rateLimiter.js crawlerTracker.js utils/ logger.js # pino 结构化日志 promptGuard.js # LLM 提示注入检测 path.js # 路径遍历防护 ``` ### 中间件链(固定顺序) ``` Helmet → CORS → JSON 解析 → 速率限制 → 爬虫追踪 → URL 去重 → 日志 → CSRF → CSRF Cookie 刷新 → 认证路由 → 验证码路由 → 版本路由 → 文档路由 → 元数据路由 → GEO 路由 → LLM 路由 → 配置路由 → 媒体路由 → 管理路由(认证 + 角色 + 密码检查) ``` ::: warning 中间件注册顺序至关重要。认证路由(login/logout)必须在管理路由之前注册,否则登录接口会被认证中间件拦截。 ::: ## 文件存储设计 ### 存储结构 ``` data/ docs/{lang}/*.md # Markdown 文档(zh/en/jp) drafts/{lang}/*.md # 草稿(AI 审核流程) geo-wiki.json # 分类/标签/用户/反馈配置 media-meta.json # 上传者信息 history/{lang}/*.json # 文档版本历史 crawler-visits.json # AI 爬虫访问日志 csrf-secret.txt # CSRF 密钥(自动生成) public/media/ # 上传的媒体文件 ``` ### 写入队列 所有文件写入通过 `enqueueWrite()` 进入串行 Promise 链。写入操作以 5 秒为周期批量合并,写入后自动调用 `invalidateCache()` 清除缓存。 **重要**:不要直接调用 `fs.writeFileSync`,始终使用 `saveDoc()`、`saveDb()` 或 `enqueueWrite()`。 ### 缓存机制 - 缓存有效期:60 秒(`CACHE_TTL_MS`) - 每次写入自动失效 - 支持手动失效:`invalidateCache()` ## 安全架构 ### 认证流程 ``` 用户登录 → 验证密码 → 生成 JWT → 设置 httpOnly Cookie ↓ 请求 API → 提取 Cookie → 验证 JWT → 检查角色 → 检查密码修改状态 ``` ### CSRF 保护 采用 Double-Submit Cookie HMAC 机制: 1. 服务器生成随机 Secret 并存入文件 2. Secret 同时写入 Cookie 和响应头 3. 客户端每次请求在 Header 中回传 Secret 4. 服务器验证 HMAC 签名 ### CSP 策略 基于 Nonce 的 Content Security Policy: - 每个请求生成唯一 Nonce - 只允许具有正确 Nonce 的脚本执行 - 通过 MutationObserver 动态注入 Nonce 到动态加载的 CSS ## API 设计 ### 公开 API 所有公开端点位于 `/api/v1/`,无需认证: | 方法 | 端点 | 说明 | |------|------|------| | GET | `/api/v1/docs` | 文档列表(分页、可过滤) | | GET | `/api/v1/docs/search` | 全文搜索 | | GET | `/api/v1/docs/:slug` | 单个文档详情 | | GET | `/api/v1/categories` | 分类列表 | | GET | `/api/v1/tags` | 标签列表 | | GET | `/api/v1/config` | 公开站点配置 | | GET | `/api/v1/llms.txt` | AI 爬虫数据 | | GET | `/api/v1/geo/sitemap.xml` | XML 站点地图 | ### 管理 API 需要认证和角色授权: | 方法 | 端点 | 说明 | |------|------|------| | POST | `/api/v1/auth/login` | 登录 | | POST | `/api/v1/auth/logout` | 登出 | | GET | `/api/v1/auth/me` | 当前用户信息 | | CRUD | `/api/v1/admin/docs` | 文档管理 | | PUT | `/api/v1/admin/docs/reorder` | 文档排序 | | CRUD | `/api/v1/admin/categories` | 分类管理 | | CRUD | `/api/v1/admin/tags` | 标签管理 | | POST | `/api/v1/media/upload` | 文件上传 | | POST | `/api/v1/admin/geo/rebuild` | 重建 GEO 文件 | ### 响应格式 ```json // 成功 { "success": true, "data": { ... } } // 分页 { "success": true, "data": [...], "pagination": { "page": 1, "limit": 20, "total": 42 } } // 错误 { "success": false, "message": "Not found" } ``` ## 部署架构 ### Docker 多阶段构建 ``` 阶段 1:构建前端 Node.js 22 → npm install → npm run build → dist/ 阶段 2:生产运行 Node.js 22 → Express.js API + Nginx 静态文件 ``` ### 环境变量 关键配置项: | 变量 | 说明 | 默认值 | |------|------|--------| | `PORT` | 服务端口 | 3002 | | `JWT_SECRET` | JWT 密钥(必填) | - | | `CORS_ORIGINS` | 允许的跨域来源 | - | | `RATE_LIMIT_*` | 速率限制配置 | 300/min |