# 通用数据同步服务 一个基于 OpenResty/Lua 的轻量级数据同步服务,用于安全存储和管理 Cookie、Token、Credential 等敏感数据,支持自动过期检测和 Web 管理界面。 ## 核心特性 - **轻量高效**:基于 OpenResty,单容器运行,内存占用 < 50MB - **安全可靠**:密码保护 + CORS 支持 + Web 界面身份验证 - **类型丰富**:支持 cookie/token/credential/session/custom 等多种数据类型 - **过期管理**:自动过期检测 + 状态监控 + 通知提醒 - **易于集成**:提供浏览器油猴脚本、Python SDK、REST API - **Web 管理**:完整的 Web 管理界面,支持查看、复制、删除数据 - **零依赖部署**:Docker Compose 一键启动,无需安装 Python/Flask --- ## 技术栈 - **Web 服务器**:OpenResty (Nginx + Lua) - **数据存储**:文件系统 JSON 格式 - **容器化**:Docker + Docker Compose - **前端界面**:纯 HTML/CSS/JavaScript - **客户端**:Python 3.7+、Tampermonkey 油猴脚本 - **API 协议**:RESTful HTTP + JSON --- ## 快速开始 ### 1. 使用 Docker 部署(推荐) ```bash # 克隆或进入项目目录 cd /home/hermes/projects/data-sync-service # 创建数据目录 mkdir -p data chmod 777 data # 启动服务 docker-compose up -d # 验证服务 curl http://localhost:5001/health # 预期输出: {"status":"ok"} ``` 服务将在 `http://localhost:5001` 启动。 ### 2. 访问 Web 管理界面 1. 浏览器访问:`http://localhost:5001/login` 2. 输入密码:`admin123123123`(生产环境请修改) 3. 进入管理面板,查看所有同步的数据 ### 3. 安装浏览器油猴脚本 1. 安装 [Tampermonkey](https://www.tampermonkey.net/) 扩展 2. 打开 `client/userscript-template.js` 3. 复制内容并创建新脚本 4. 修改配置中的 `serverUrl` 和 `password` 5. 保存并启用脚本 ### 4. 一键同步数据 在支持的网站(通义听悟、微信公众号等): 1. 登录你的账号 2. 点击页面右侧悬浮的 **🔄 同步数据** 按钮 3. 选择 **立即同步** 4. 看到 ✅ 成功提示 --- ## API 文档 ### 健康检查 检查服务运行状态。 ```bash GET /health ``` **响应示例**: ```json { "status": "ok" } ``` --- ### 上传/更新数据 上传或更新指定标签的数据。 ```bash POST /api/data Content-Type: application/json ``` **请求体**: ```json { "password": "admin123123123", "tag": "tingwu:user@example.com", "type": "cookie", "data": { "cookies": [ { "name": "session_id", "value": "abc123xyz", "domain": ".example.com", "path": "/", "secure": true, "httpOnly": false } ], "raw_cookie": "session_id=abc123xyz; token=...", "user_agent": "Mozilla/5.0 ..." }, "metadata": { "expires_in": 604800, "note": "通义听悟账号", "login_url": "https://tingwu.aliyun.com/" } } ``` **字段说明**: - `password`:服务密码(必填) - `tag`:数据标签,格式:`项目名:账号名`(必填) - `type`:数据类型,可选值:`cookie`/`token`/`credential`/`session`/`custom`(必填) - `data`:实际数据内容(必填,格式根据类型自定义) - `metadata.expires_in`:过期时间(秒),如 `604800` = 7天 - `metadata.note`:备注说明 - `metadata.login_url`:登录页面 URL **响应示例**: ```json { "success": true, "message": "Data saved", "tag": "tingwu:user@example.com", "timestamp": "2026-08-14 12:00:00" } ``` --- ### 获取数据 通过标签获取存储的数据。 ```bash GET /api/data/:tag X-Password: admin123123123 ``` **响应示例**: ```json { "tag": "tingwu:user@example.com", "type": "cookie", "data": { "cookies": [...], "raw_cookie": "...", "user_agent": "..." }, "metadata": { "created_at": "2026-08-14 10:00:00", "updated_at": "2026-08-14 12:00:00", "expires_at": "2026-08-21 12:00:00", "expires_in": 604800, "note": "通义听悟账号", "login_url": "https://tingwu.aliyun.com/" } } ``` --- ### 列出所有数据 获取所有存储数据的索引列表。 ```bash GET /api/data ``` **响应示例**: ```json { "tags": { "tingwu:user@example.com": { "tag": "tingwu:user@example.com", "type": "cookie", "file": "tingwu_user_example_com.json", "created_at": "2026-08-14 10:00:00", "updated_at": "2026-08-14 12:00:00", "expires_at": "2026-08-21 12:00:00", "status": "valid" }, "wechat:admin": { "tag": "wechat:admin", "type": "cookie", "file": "wechat_admin.json", "created_at": "2026-08-13 15:30:00", "updated_at": "2026-08-14 08:00:00", "expires_at": "2026-08-15 08:00:00", "status": "expiring_soon" } } } ``` **状态说明**: - `valid`:正常有效(距离过期 > 2天) - `expiring_soon`:即将过期(距离过期 < 2天) - `expired`:已过期 - `no_expiry`:无过期时间 --- ### 删除数据 删除指定标签的数据。 ```bash DELETE /api/data/:tag X-Password: admin123123123 ``` **响应示例**: ```json { "success": true, "message": "Data deleted", "tag": "tingwu:user@example.com" } ``` --- ### 获取复制配置 获取用于油猴脚本配置的格式化文本。 ```bash GET /api/data/copy/:tag ``` **响应示例**: ```json { "copy_text": "{\"serverUrl\":\"http://47.122.126.244:5001\",\"password\":\"admin123123123\",\"tag\":\"tingwu:user@example.com\",\"type\":\"cookie\"}", "formatted": "```json\n{...}\n```" } ``` --- ## 配置说明 ### 修改服务密码 编辑 `nginx/nginx.conf`,全局替换默认密码: ```bash cd /home/hermes/projects/data-sync-service sed -i 's/admin123123123/YOUR_SECURE_PASSWORD/g' nginx/nginx.conf docker-compose restart ``` 同时需要更新: - Python 客户端:修改 `scripts/utils.py` 中的 `PASSWORD` - 油猴脚本:修改 `CONFIG.password` - Web 管理界面登录密码 ### 修改服务端口 编辑 `docker-compose.yml`: ```yaml services: nginx: ports: - "8080:80" # 修改为你需要的端口 ``` 重启服务: ```bash docker-compose up -d ``` ### 添加新的项目支持 编辑 `client/userscript-template.js`,在 `PROJECT_PATTERNS` 中添加: ```javascript const PROJECT_PATTERNS = { // 现有配置... 'example.com': { project: 'example', accountSelector: '.user-email, .account-name', loginUrl: 'https://example.com/login' } }; ``` 同时在 `@match` 指令中添加匹配规则: ```javascript // @match https://example.com/* ``` --- ## 使用示例 ### Python 客户端示例 ```python import sys sys.path.append('/home/hermes/projects/data-sync-service/scripts') from utils import upload_data, get_data, list_all_tags, load_cookies_from_sync # 1. 上传 Cookie 数据 success = upload_data( tag="myapp:user@example.com", data_type="cookie", data={ "cookies": [...], "raw_cookie": "session=abc123; token=xyz789" }, expires_in=604800, # 7天 note="我的应用账号", login_url="https://myapp.com/login" ) # 2. 获取数据 data = get_data("myapp:user@example.com") if data: print(f"类型: {data['type']}") print(f"创建时间: {data['metadata']['created_at']}") print(f"过期时间: {data['metadata']['expires_at']}") # 3. 便捷方式加载 Cookie cookies = load_cookies_from_sync("tingwu:user@example.com") if cookies: # 转换为 requests 可用格式 cookie_dict = {c['name']: c['value'] for c in cookies} import requests response = requests.get( "https://tingwu.aliyun.com/api/endpoint", cookies=cookie_dict ) # 4. 列出所有数据 tags = list_all_tags() for item in tags.values(): print(f"{item['tag']} - {item['status']}") ``` ### Bash/cURL 示例 ```bash # 上传数据 curl -X POST http://localhost:5001/api/data \ -H "Content-Type: application/json" \ -d '{ "password": "admin123123123", "tag": "test:demo", "type": "token", "data": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer" }, "metadata": { "expires_in": 3600, "note": "测试 Token" } }' # 获取数据 curl http://localhost:5001/api/data/test:demo \ -H "X-Password: admin123123123" # 列出所有数据 curl http://localhost:5001/api/data # 删除数据 curl -X DELETE http://localhost:5001/api/data/test:demo \ -H "X-Password: admin123123123" ``` ### JavaScript/Fetch 示例 ```javascript // 上传数据 async function uploadData(tag, type, data) { const response = await fetch('http://localhost:5001/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password: 'admin123123123', tag: tag, type: type, data: data, metadata: { expires_in: 604800, note: '通过 JS 上传' } }) }); return await response.json(); } // 获取数据 async function getData(tag) { const response = await fetch(`http://localhost:5001/api/data/${tag}`, { headers: { 'X-Password': 'admin123123123' } }); return await response.json(); } // 使用示例 const result = await uploadData('myapp:user', 'cookie', { cookies: document.cookie.split(';').map(c => { const [name, value] = c.trim().split('='); return { name, value }; }) }); console.log('上传结果:', result); ``` --- ## 定时过期检测 ### 设置定时任务 过期检测脚本会扫描所有数据,标记即将过期(< 2天)和已过期的数据,并输出通知信息。 **手动运行**: ```bash python3 /home/hermes/projects/data-sync-service/scripts/check_expiry.py ``` **使用 cron 定时运行**: ```bash # 编辑 crontab crontab -e # 添加定时任务(每天上午 9 点检查) 0 9 * * * cd /home/hermes/projects/data-sync-service && python3 scripts/check_expiry.py ``` ### 检测输出示例 ``` ❌ 数据已过期 Tag: wechat:admin 类型: cookie 过期时间: 2026-08-13 08:00:00 请重新登录同步: https://mp.weixin.qq.com/ 配置信息(点击复制): ```json { "serverUrl": "http://47.122.126.244:5001", "password": "admin123123123", "tag": "wechat:admin", "type": "cookie" } ``` ⚠️ 数据即将过期 Tag: tingwu:user@example.com 类型: cookie 剩余时间: 1.5 天 过期时间: 2026-08-15 18:00:00 建议重新登录同步: https://tingwu.aliyun.com/ 📊 数据状态统计 ❌ 已过期: 1 个 ⚠️ 即将过期: 1 个 ✅ 正常: 3 个 ``` --- ## 部署指南 ### 生产环境部署 1. **修改默认密码**(重要!) ```bash cd /home/hermes/projects/data-sync-service sed -i 's/admin123123123/YOUR_STRONG_PASSWORD/g' nginx/nginx.conf docker-compose restart ``` 2. **配置 HTTPS(推荐)** 使用 Nginx 反向代理: ```nginx # /etc/nginx/sites-available/data-sync server { listen 443 ssl http2; server_name sync.yourdomain.com; ssl_certificate /etc/ssl/certs/your-cert.pem; ssl_certificate_key /etc/ssl/private/your-key.pem; location / { proxy_pass http://127.0.0.1:5001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` 3. **配置防火墙** ```bash # Ubuntu/Debian sudo ufw allow 5001/tcp sudo ufw enable # 或限制 IP 访问 sudo ufw allow from 192.168.1.0/24 to any port 5001 ``` 4. **数据备份** ```bash # 手动备份 tar -czf data-backup-$(date +%Y%m%d).tar.gz data/ # 定时备份(添加到 crontab) 0 2 * * * cd /home/hermes/projects/data-sync-service && tar -czf backups/data-$(date +\%Y\%m\%d).tar.gz data/ ``` ### 外网访问配置 修改客户端配置中的 `serverUrl`: - Python 客户端:`scripts/utils.py` → `SERVER_URL` - 油猴脚本:`client/userscript-template.js` → `CONFIG.serverUrl` ```python # scripts/utils.py SERVER_URL = "https://sync.yourdomain.com" ``` ```javascript // client/userscript-template.js const CONFIG = { serverUrl: 'https://sync.yourdomain.com', password: 'YOUR_SECURE_PASSWORD' }; ``` --- ## 目录结构 ``` /home/hermes/projects/data-sync-service/ ├── docker-compose.yml # Docker Compose 配置 ├── nginx/ │ └── nginx.conf # OpenResty/Nginx 配置(核心 API 实现) ├── web/ │ ├── index.html # Web 管理界面 │ └── login.html # 登录页面 ├── data/ # 数据存储目录(挂载到容器) │ ├── index.json # 数据索引文件 │ ├── tingwu_*.json # 数据文件(tag → 文件名映射) │ └── *.json # 其他数据文件 ├── scripts/ # 工具脚本 │ ├── check_expiry.py # 过期检测脚本 │ ├── clean_expired.py # 清理过期数据 │ ├── migrate.py # 数据迁移工具 │ └── utils.py # Python SDK 工具库 ├── client/ │ └── userscript-template.js # Tampermonkey 油猴脚本模板 ├── clients/ │ └── client-example.py # Python 客户端使用示例 ├── README.md # 本文档 ├── DEPLOYMENT.md # 详细部署指南 └── .gitignore # Git 忽略配置 ``` --- ## 故障排查 ### 服务无法启动 ```bash # 查看容器日志 docker-compose logs -f # 检查端口占用 sudo lsof -i:5001 # 或 netstat -tlnp | grep 5001 # 检查数据目录权限 ls -la data/ chmod 777 data/ ``` ### API 返回 401 Unauthorized - 检查请求中的密码是否正确 - POST 请求:检查 JSON body 中的 `password` 字段 - GET/DELETE 请求:检查 HTTP 头 `X-Password` 是否设置 ### 数据无法保存 ```bash # 检查磁盘空间 df -h # 检查数据目录权限 ls -la data/ chmod 777 data/ # 进入容器检查 docker exec -it data-sync-service sh ls -la /data ``` ### 油猴脚本无反应 1. 打开浏览器开发者工具(F12)查看控制台错误 2. 确认当前网站 URL 匹配 `@match` 规则 3. 检查 `CONFIG.serverUrl` 是否可访问 4. 确认服务器防火墙/CORS 配置 ### Web 界面无法登录 - 确认密码是否为 `nginx/nginx.conf` 中配置的密码 - 检查浏览器 Cookie 是否被禁用 - 清除浏览器缓存和 Cookie 后重试 --- ## 性能指标 - **内存占用**:~20-50MB(OpenResty 容器) - **磁盘占用**:~10KB/数据项(JSON 格式) - **响应时间**:< 10ms(本地文件读写) - **并发能力**:1000+ req/s(Nginx/Lua) - **启动时间**:< 2秒 --- ## 安全建议 1. **生产环境必须修改默认密码** 2. **使用 HTTPS 加密传输**(通过 Nginx 反向代理) 3. **限制 IP 访问范围**(防火墙 + Nginx allow/deny) 4. **定期备份数据目录** 5. **不要在公网暴露 5001 端口**(使用反向代理) 6. **定期清理过期数据**(运行 `clean_expired.py`) 7. **审计数据访问日志**(查看 Docker 日志) --- ## 与其他项目集成 ### 在自动化脚本中使用 ```python #!/usr/bin/env python3 import sys sys.path.append('/home/hermes/projects/data-sync-service/scripts') from utils import load_cookies_from_sync, load_token_from_sync # 从同步服务加载 Cookie cookies = load_cookies_from_sync("tingwu:user@example.com") if cookies: # 使用 Cookie 进行自动化操作 import requests session = requests.Session() for cookie in cookies: session.cookies.set(cookie['name'], cookie['value'], domain=cookie.get('domain')) # 发起请求 response = session.get("https://tingwu.aliyun.com/api/v1/tasks") print(response.json()) else: print("Cookie 已过期,请重新同步") sys.exit(1) ``` ### 降级方案 当同步服务不可用时,可以降级到本地文件: ```python def load_cookies_with_fallback(tag): """优先从同步服务加载,失败时使用本地文件""" from utils import load_cookies_from_sync import json # 尝试从同步服务加载 cookies = load_cookies_from_sync(tag) if cookies: return cookies # 降级到本地文件 local_path = f"/path/to/local/{tag.replace(':', '_')}.json" try: with open(local_path, 'r') as f: data = json.load(f) return data.get('cookies', []) except: return None ``` --- ## 支持的项目 ### 已内置支持 1. **通义听悟**(tingwu.aliyun.com) - 自动检测账号邮箱 - 同步所有 Cookie - 7天过期提醒 2. **微信公众号**(mp.weixin.qq.com) - 自动检测账号昵称 - 同步登录 Cookie - 7天过期提醒 ### 自定义项目 参考 [添加新的项目支持](#添加新的项目支持) 章节。 --- ## 常见问题(FAQ) **Q: 数据存储在哪里?** A: 数据以 JSON 格式存储在 `data/` 目录下,每个 tag 对应一个文件。 **Q: 支持多少个 tag?** A: 无限制,每个 tag 对应一个独立的 JSON 文件。 **Q: 可以存储哪些类型的数据?** A: 任何 JSON 可序列化的数据,常见类型包括:cookie、token、credential、session、API key、配置信息等。 **Q: 如何备份数据?** A: 直接备份 `data/` 目录即可:`tar -czf backup.tar.gz data/` **Q: 支持集群部署吗?** A: 当前版本基于文件存储,不支持集群。如需集群部署,建议改为使用 Redis 或数据库存储。 **Q: 如何迁移到新服务器?** A: 复制整个项目目录,确保 `data/` 目录权限为 777,然后 `docker-compose up -d`。 **Q: 密码存储安全吗?** A: 密码以明文存储在 `nginx.conf` 中,建议使用环境变量或外部密钥管理服务。 **Q: 支持多用户吗?** A: 当前版本为单用户设计(共享密码),如需多用户支持,需要修改 Nginx 配置添加用户认证系统。 --- ## 更新日志 ### v1.0.0 (2026-08-14) - ✨ 重构为 OpenResty/Lua 架构,移除 Flask 依赖 - ✨ 新增 Web 管理界面(带身份验证) - ✨ 新增数据状态实时检测(valid/expiring_soon/expired) - ✨ 新增一键复制配置功能 - ✨ 优化 Docker 镜像大小(50MB) - ✨ 改进 CORS 配置 - 🐛 修复索引结构(改为对象格式) - 📝 完善 API 文档和使用示例 --- ## 许可证 本项目仅供个人学习和内部使用,请勿用于非法用途。使用本服务存储和传输敏感数据时,请确保符合相关法律法规。 --- ## 贡献 欢迎提交 Issue 和 Pull Request! **作者**:K-hermes **项目地址**:`/home/hermes/projects/data-sync-service` --- ## 相关文档 - [详细部署指南](DEPLOYMENT.md) - 生产环境部署、监控、备份 - [验收测试](ACCEPTANCE.md) - 功能测试清单 - [技术总结](SUMMARY.md) - 技术选型和设计决策