文件
wangchuanli f36149efc3 feat(安全): 对外暴露面加固 + 界面去 AI 化(v1.5.0)
界面(去 AI 味):
- 大屏页清除 114 处生成器残留属性 data-page-node-id
- 视觉系统改回工程控制台风格:去 radial/linear-gradient、去辉光、
  去标题前彩色装饰条,改为中性灰阶 + 单一蓝色强调色;KPI 色条改状态点
- 精简各页说教式长提示;修掉 profile.html 泄漏到页面上的 Markdown 星号
- 删除登录页过时的「默认账号 admin / admin123」提示(1.4.0 起已无默认口令)

安全与隐私(按「将会被公网访问」收口):
- 内部异常只回 8 位事件号,完整堆栈进服务端日志(web/api.py::_internal)
- 导出文件名收敛:防响应头注入与路径穿越;manage.py passwd 补用户名校验
- 登录对不存在的账号也走一次哑哈希,抹平用户名枚举的时序差异
- /api/* 读接口限速 240 次 / 60 秒 / 账号(挡住循环调 /api/bundle)
- 进程 umask 0077 + 目录 0700 / 文件 0600:对话正文与主密钥的落盘权限
- 表名与库文件路径只对管理员下发;大屏页所有数据插值转义
- --debug 只允许绑定回环地址;新增 Permissions-Policy 与 413 处理器

文档:
- DEPLOYMENT 新增第十三节「安全与隐私基线」;迁移表补 1.4.0 → 1.5.0 行
- SECURITY 更新支持范围、新增「信息泄漏收敛」小节与上线检查项
- .codebuddy/ 加入 .gitignore(助手工作记忆不进仓库)

版本:1.4.0 → 1.5.0(无库结构变更,user_version 仍为 4)
验证:python tools/smoke.py → ok=264 fail=0;python tools/check_docs.py → 0 处问题
2026-09-18 11:13:17 +08:00

47 KiB

用户使用指南

面向使用者(不是开发者)。读完这份就能独立完成日常操作: 注册 / 登录 → 配好自己的凭证 → 看用量 → 查明细 → 导数据 → 处理常见异常。

装服务的人看 部署与运维指南。注册进来的账号是普通账号, 权限范围见 第三章 —— 这一章请务必读一遍。

关于配图:本文所有截图都用 tools/demo_data.py 生成的合成示例数据渲染 —— 模型名统一是 demo-*,客户端为 vscode/webconsole/sdk,Prompt 是通用示例文本, Cookie 是假串(wb_demo_session=…),账号是 admin 与 demo 两个。 所以你可以照着重现出几乎一样的界面,也不必担心文档里夹带真实账号信息。 想自己搭一份这样的环境:python tools/demo_data.py 然后按输出的提示起服务即可。

目录


一、这个系统是做什么的

它把 WorkBuddy 账号的积分用量明细自动采集下来,存成一份永久全量存档,并提供查询与可视化。

为什么不直接看官网?官网只给一段时间窗口的明细,过期就查不到了;导出的 xlsx 还会丢掉 约 22% 的 User Prompt 内容。本系统把数据落到自己的库里,只增不减,随时能翻旧账。

一次典型的日常是:

管理员把采集时刻统一设好(默认 09:00 / 17:00),服务端到点自动采集
   ↓
你注册 / 登录 后做的第一件事:粘贴自己的 Cookie(否则采集会跳过你)
   ↓
想看进度  →  「概览」看今天用了多少
想深挖    →  「用量大屏」按模型 / 客户端 / 时段切
要找某条  →  「数据明细」搜索 + 展开 Prompt
要拿给别人 →  「数据明细」→ 导出 CSV

每个账号只看得见自己的数据,这一点在下面第三章展开。


二、注册与登录

2.1 登录

打开 http://<部署机器IP>:8848,会看到登录页。

登录页

项目 说明
默认管理员 admin / admin123(只有数据库里一个账号都没有时才会创建)
登录保持 12 小时
验证码 默认始终要求,4 位,不区分大小写,5 分钟内有效、只能用一次
失败限制 同一 IP、或同一用户名连续错 5 次,锁定 10 分钟
退出 右上角「退出」(走 POST,防被恶意链接静默触发)

关于验证码:

  • 图上只有数字与字母,并且去掉了容易看错的 0 O 1 I L;
  • 看不清就点图片换一张,不消耗任何额度;
  • 一张验证码用完即废:输错要换新的,登录用过之后也不能再拿去注册;
  • 答案只存在服务器数据库里,浏览器拿到的只是一个随机编号 —— 在网页源码里搜不到答案;
  • 被锁定期间,即使验证码填对也会被拒,等 10 分钟或换一个来源。

⚠️ 如果你是管理员且是首次部署:立刻改密码(admin123 等于没锁门)。 改法:「个人中心 → 修改登录密码」,或命令行 python manage.py passwd admin 新密码。

2.2 自助注册

登录页底部有「自助注册」入口(地址是 /register)。管理员也可以把这个入口关掉。

注册页

字段 要求
用户名 3~32 位,字母或数字开头,可含 _ . -;这是登录名,注册后不可改
显示名 选填,留空则与用户名相同
邮箱 选填,便于日后找回
密码 至少 8 位,且含大写字母 / 小写字母 / 数字 / 符号中的至少两类
验证码 与登录页同款:5 分钟有效、一次性

批量注册被三道闸门挡着:

  1. 图形验证码 —— 每次提交都要重新过一遍;
  2. 来源限额 —— 同一个 IP 每天最多注册 3 个账号(管理员可调);
  3. 总开关 —— 管理员可以随时关闭注册入口。

注册成功后你是什么权限

注册出来的账号一律是「普通账号」。普通账号能做的事只有一件配置相关的: 维护你自己的 Cookie 和 User-Agent。

定时任务的频率、采集参数、日志查看这些都属于管理员,你看到的是只读的。 详细清单见下一章。

注册成功后不会自动帮你配好采集。你要粘贴的是你自己账号的 Cookie, 见 第四章。在那之前,概览页只会提示「未配置凭证」, 采集到点时会跳过你并记一条 no_cookie。


三、权限与数据边界

这是本系统最要紧的一章。先看清自己能用什么,比急着点按钮有用。

3.1 两张身份

管理员 普通账号(你注册后拿到的)
谁能拿到 首个部署账号,或由管理员授权 自助注册,或由管理员创建
配置权限 全部 只能维护本人的 Cookie / User-Agent
调度设置 可改(实例级,对所有人生效) 只读(看不到也改不了频率)
日志查看 可看全实例日志与审计 无权限(导航里不显示,直接访问返回 403)
用户管理 可建号 / 停用 / 删号 / 改权限 无权限(同上)
看数据 只看自己的 只看自己的

3.2 你的权限清单

能力 普通账号
登录 / 退出 / 改自己的资料与密码 ✅
配置本人的 Cookie 与 User-Agent ✅ 这是你唯一可改的配置
查看概览、用量大屏 ✅(只有你自己的数据)
查看 / 搜索数据明细、展开 Prompt ✅(只有你自己的记录)
导出 CSV(当前筛选条件) ✅(只有你自己的记录)
导出我的全部数据(zip:记录 / 采集历史 / 审计 / 账号与配置) ✅ 不含 Cookie 明文,见 10
手动「立即采集一次」、按区间补采 ✅(只采你自己的,且有频率与跨度限制,见 8.2)
「补全 Prompt」「导出我的 CSV」 ✅(只动你自己的)
查看采集运行历史 ✅(只有你自己的)
设置定时任务频率 / 开关 / 补跑策略 ❌ 只读
改采集参数(分页、超时、截断、证书校验…) ❌ 只读
查看日志管理页 / 应用日志 ❌ 403
改实例级设置(接口地址、开放注册、验证码策略) ❌
用户管理(建号 / 停用 / 删号 / 改权限) ❌ 403
备份管理:下载数据库归档、从备份恢复 ❌ 403(恢复等于对全库数据有完整读写权,只给管理员)
整理数据库(VACUUM,整库操作) ❌

为什么调度不给你改:采集策略是整机一套的(一台部署一个调度时刻表, 所有账号在同一时刻被采集)。如果每个账号各定时刻,同一分钟里会有多个采集 抢同一把写锁 —— SQLite 是单写者,那样只会互相拖慢。

你需要「马上采一次」的时候,用「任务管理 → 立即采集一次」,随时可用,不受调度限制。

3.3 数据边界:你能看到什么

是「你的」 是「共用的 / 管理员管」
Cookie 与 User-Agent 接口基址与路径
用量记录、采集历史、导出的 CSV / zip 采集调度时刻表与全部采集参数
个人资料、登录密码 是否开放自助注册、注册限额、验证码策略
— 数据库文件本身、应用日志、数据库备份归档

三条值得记牢:

  • 管理员也看不到你的 Cookie。 它在数据库里是密文,页面上永远只回显 「长度 + 结尾 4 位」,形如 1238 字符,结尾 …c0ffe。
  • 管理员也看不到你的用量明细内容。 用户管理页只显示每个账号的 记录条数 / 积分合计 / 最后登录时间与 IP —— 只给「有多少」,不给「是什么」。
  • 采集只使用本人的凭证。 系统不会拿别人的 Cookie 去替你采集(那会串号), 所以每个账号都必须各自配一次 Cookie。
  • 但备份是管理员的能力:管理员能下载整个数据库的归档、也能用归档覆盖回来。 这是运维必需(不然数据丢了没人能救),代价是管理员对全库数据有完整的读写权。 介意这一点的话,就自己用「导出我的全部数据」留一份,见 10。

四、配置你唯一的配置项:Cookie

没有 Cookie,采集一定失败。 这是每个账号各自要做一次的手工步骤, 也是普通账号唯一需要动手的配置。

4.1 为什么要 Cookie,以及它怎么被保管

采集是直接调账号的用量接口,云端靠 Cookie 认人。Cookie 等于账号凭证,所以系统对它:

  • 加密后入库:落库前用 ChaCha20 + HMAC-SHA256 加密(主密钥在 data/instance.json, 与数据库文件分开放),数据库被拷走也读不出明文;
  • 永不回传明文:页面与接口只回显「多少字符、结尾 4 位」;
  • 只属于你:存在你的账号名下,别人(包括管理员)看不到、也拿不到;
  • 和 User-Agent 绑在一起:两者必须取自同一次浏览器请求,否则云端会认为是另一个客户端。

「配置管理 → 我的云端凭证」里如果出现 无法解密 的红字提示,说明实例主密钥被换过 (data/instance.json 被删或被替换),重新粘贴一次即可。详见 十四、常见问题。

办法 A:让程序自己从编辑器设置里读(最省事)

如果你平时用 VSCode / Cursor / Trae 登录过 WorkBuddy,Cookie 已经在本机设置里:

python manage.py import-creds              # 不指定 -u 时给「管理员」账号导入
python manage.py import-creds -u alice     # 想导给谁就写谁的用户名

它会去读编辑器 settings.json 里的 codebuddyUsage.* 字段,写进数据库。

⚠️ 导入的是运行这条命令的那台机器上、那个编辑器账号的 Cookie。 如果 A 同事的机器上跑这条命令去给 B 同事的账号导入,采到的就是 A 的数据 —— 所以更稳的做法是自己登录网页、粘贴自己的 Cookie(就是下面的办法 B)。 另外这条命令需要能访问部署机器,普通账号通常直接走办法 B。

办法 B:手工复制(一定可行,推荐)

  1. 浏览器打开并登录 WorkBuddy 官网;
  2. 按 F12 打开开发者工具 → 切到 Network(网络) 标签;
  3. 刷新页面,随便点一个发往 workbuddy.cn 的请求;
  4. 在 Request Headers(请求标头) 里找到 Cookie: 一行;
  5. 整行值复制下来(很长,通常几千字符,要复制完整);
  6. 到本系统「配置管理 → 我的云端凭证」,粘贴到 Cookie 输入框,保存。

顺手把 User-Agent 也填成同一个浏览器的 UA,成功率高一些。

保存后到「任务管理 → 立即采集一次」,然后看该页「运行历史」里那一条的记录:

看到 含义 怎么办
新增 N 条 或 无新增(已是最新) ✅ 正常 —
cookie_expired / 401 / 403 Cookie 过期了 重新执行 4.2
no_cookie(采集被跳过) 你还没配 Cookie 按 4.2 填一份
cookie_broken 密文解不开(实例主密钥被换过) 重新粘贴一次,见 十四
TLS / SSLError 证书校验失败 找管理员(ssl_verify 是实例级参数,你改不了)

普通账号看不到「日志管理」页,但采集运行历史在「任务管理」页下方就有 —— 排错够用了。整机应用日志和操作审计属于管理员。


五、概览页:一眼看清家底

登录后的首页。

概览页

从上到下四块:

1. KPI 卡片(6 个) —— 只统计归属你本人的数据,别人的记录不会算进来。

卡片 含义
存档总量 你名下有多少条记录(只增不减)
累计积分 你名下全部记录的积分合计
活跃天数 有记录的自然日数量
今日积分 今天(本地时区)已消耗
今日 vs 昨日 今日与昨日整日对比,带涨跌幅
采集健康 最近若干次采集的成功 / 失败情况

2. 今日 vs 昨日整日 注意「昨日」是完整一天,而「今日」还在进行中 —— 上午看数字偏低是正常的, 该跟昨天的同一时段比才有意义(大屏页能做这个对比)。

3. 调度状态 显示调度开关、下次执行时刻、上次采集结果。 普通账号这里显示的时刻是只读的 —— 它由管理员统一设定, 提示会写「时刻由管理员统一设定,你可以在任务管理里查看,也可以随时手动采集本人数据」。

4. 模型 TOP + 最近采集 按模型看积分消耗排行;下方是最近几次采集的触发方式(手动 / 调度 / 启动补跑)、 耗时、抓取条数、新增条数、去重条数。运行号对普通账号是纯文本(不能点进日志页)。

若你还没配 Cookie,页面顶部会有醒目提示引导你去「配置管理」—— 在那之前采集到点会跳过你。


六、用量大屏:交互式分析

左侧导航点「用量大屏」,或直接访问 /dashboard。

大屏首页

大屏是独立的交互页,顶部可切时间区间(今日 / 近 7 天 / 近 30 天 / 自定义), 所有图表联动重绘。主要图表:

图 看什么
日历热力图 哪几天用得猛(颜色越深越多)。注意:格子颜色是「该日合计」,不是单条
趋势折线 按天的积分走势,判断是否在加速
维度分布 按模型或客户端拆分的占比
时段分布 24 小时里集中在哪些时段(配合判断是否有脚本在跑)
单笔 TOP 最贵的单次请求,含 Prompt 摘要 —— 最值得优化成本的地方

大屏交互

页面左上角有「← 返回后台」入口,随时能回管理后台。 大屏的数据是按当前筛选窗口实时取的,不是预生成的静态图 —— 切区间会重新请求。 大屏同样是按账号隔离的:你只会看到自己的数据。

怎么用它省钱:先看「单笔 TOP」抓出最贵的请求类型,再看「时段分布」判断是不是 某个自动化任务在固定时间跑,最后用「数据明细」把那一批记录导出来逐条分析。


七、数据明细页:查、筛、导

数据明细页

7.1 筛选条件

条件 说明
快捷区间 「今日 / 近 7 天 / 近 30 天 / 全部」一键填日期
日期 起 / 止,留空表示不限
模型 下拉,来自库里实际出现过的模型
客户端 下拉,来源客户端标识
关键词 在 Prompt 正文里模糊匹配
每页条数 20 ~ 500
排序 时间倒序 / 正序、积分从高到低等

日期写错格式(如 abc、2026-13-99)不会白屏,系统会忽略非法值并提示。

7.2 看单条的完整 Prompt

列表默认不显示 Prompt 全文(它占数据体积约 80%)。点行首的「展开」看该条的完整 Prompt。 想批量看就导出 CSV。

7.3 导出 CSV

点「导出 CSV」,会把当前筛选条件下的全部记录(不是当前页)流式导出, 文件名形如 usage_2026-09-01_2026-09-14.csv。

  • 编码为 UTF-8 带 BOM,Excel 双击直接打开不乱码;
  • 列与官网导出的 xlsx 完全同构:requestId, credits, prompt, model, client, requestTime;
  • 数据量大时也是边查边吐,不会把服务器内存吃满;
  • 导出的只有你自己的记录,不含任何别人的数据。

八、任务管理页:手动采集与只读的调度

任务管理页(普通账号视图)

8.1 调度信息(只读)

普通账号在「采集调度」这块看到的是只读表格,不是表单:

项 你看到的
启用调度 开关状态(由管理员设定)
每日时刻 如 09:00,17:00(由管理员设定)
启动补跑 / 补跑宽限期 由管理员设定
采集参数 去「配置管理」看,同样是只读

页面上会明确写着「调度时刻与采集参数由管理员统一设定,普通账号只读」。 要是你需要改时刻,找管理员 —— 这是整机一套的策略。

为什么这么设计:一台部署只有一个调度线程,所有账号在同一时刻被采集。 让大家各定时刻只会让多个采集抢同一把写锁(SQLite 单写者),互相拖慢。

但你随时可以手动采。 需要「现在就采一次」时用下面的按钮,不受调度限制。

8.2 手动采集(你可以用)

  • 立即采集一次:按断点续采,最常用的按钮。
  • 按区间补采:填 起 / 止,把这几天重新扫一遍。 用途:换了 Cookie 之后回补漏掉的日期;或怀疑某天数据不全时重扫。 重扫不会产生重复 —— 主键去重,已存在的记录按「更早的本地时间」保留。

这两个动作只采集你自己的数据,不会碰到别人的。

三条限制(v1.4.0 起,页面上会写出来):

限制 表现 为什么
有任务在跑时不能再发起 点「立即采集」返回「正在采集,请等它结束」 SQLite 是单写者,并发采集只会互相拖慢,还可能把云端接口打得太密
两次手动采集之间有最小间隔(默认 60 秒) 返回「操作太频繁,请 N 秒后再试」 防止反复点按钮把请求刷爆
单次最长跨度 31 天(约 1 个月) 起始日期填得太早会被自动收窄,运行日志里出现一行 [warn] 请求跨度超过上限 N 天,已自动收窄起点 避免一次拉取过长周期的数据(云端要分很多页,慢且容易失败)

想补更久以前的数据?分几次做:比如先补 1 月,再补 2 月。 跨度过长的请求不是被拒就是跑到一半超时,分段的成功率反而更高。

8.3 运行历史

每次采集都留一条记录:触发方式、状态、耗时、抓取 / 新增 / 去重条数、退出码。 你能看到的只有你自己的运行历史。

「日志」列在普通账号下显示为 —。逐行日志原文在「日志管理」页, 那是管理员专属(你访问会返回 403)。


九、配置管理页

配置管理页(普通账号视图)

9.1 我的云端凭证(这是你唯一能改的配置)

字段 说明
Cookie 你本人账号的凭证,密文入库。留空保存 = 不修改;填一个 - = 清空已保存的 Cookie
User-Agent 与拿 Cookie 的浏览器保持一致更稳(两者必须取自同一次请求)

保存后页面上只显示 当前 Cookie:1238 字符,结尾 …c0ffe(2026-09-15 10:22 更新) —— 页面上、接口里都拿不到明文。若显示「无法解密」的红字横幅,说明实例主密钥被换过, 重新粘贴一次即可。

凭证卡片上会有一行提示写着「普通账号只有这一块可改」——看到它就找对地方了。

9.2 采集参数(只读)

普通账号在这一块看到的是只读表格,输入框不可编辑:

参数 默认 说明
api_base https://www.workbuddy.cn 接口基址(镜像 / 代理时改)
api_path /billing/meter/get-user-request-usage 接口路径
page_size 200 单页条数(20 ~ 1000)
rewind_minutes 2 断点回退分钟数(0 ~ 120)
drift_tolerance_minutes 5 云端时间漂移告警阈值(0 ~ 720)
max_prompt 2048 Prompt 入库截断长度,0 = 不截断
verify_days 0 每次采集后做整日完整性校验的天数
timeout 30 单次 HTTP 超时(秒)
ssl_verify 1(开) 校验云端 HTTPS 证书,只在自签 / 企业代理场景才关

为什么只读:这些参数决定「一次采集怎么发请求」,属于实例级策略。 特别是 ssl_verify —— 谁能关掉它,谁就能让这台服务器在不校验证书的情况下 把所有人的 Cookie 发出去。这类开关必须收在管理员手里。

你确实需要调其中某一项时,把需求和理由告诉管理员,由他统一改 —— 改完对所有人立即生效,不用重启。

9.3 维护动作

按钮 作用 何时用 普通账号
补全 Prompt 把缺失的 Prompt 从云端回补 从官网 xlsx 导入过数据后(xlsx 丢约 22%) ✅ 只补自己的
导出我的 CSV 导出你自己的全量数据到 data/exports/ 归档 / 交接 ✅
整理数据库 wal_checkpoint + VACUUM(整库操作) 删过数据后回收空间 ❌ 仅管理员

这些动作耗时且会占用写权限,所以有二次确认。执行期间不要重复点击。

9.4 修改密码

填「当前密码 / 新密码 / 确认新密码」。改完当前会话仍然有效,其他会话需要重新登录。 (同样的表单在「个人中心」也有一份。)

9.5 实例级设置(仅管理员可见)

普通账号看不到这一块。它包含「开放自助注册 / 同 IP 注册上限 / 验证码策略 / 验证码位数」,改动对所有账号生效。见 第十一章。


十、个人中心

点右上角你自己的名字,进入个人中心(/profile)。

个人中心

区块 能做什么
四张卡片 我的记录数 / 我的积分 / 采集次数 / 我的 Cookie 状态
修改资料 改显示名、邮箱(用户名只读)
修改登录密码 需要原密码。改成功后其他设备上的登录会立刻失效(本机这次会话保留,不然改完立刻被自己踢下线)
我的采集凭证 是否已配置、多少字符、结尾 4 位、最后更新时间、当前调度时刻(只读)
导出我的全部数据 下载一个 zip,把属于你的东西一次带走(见下)

顶栏右侧会有一个 「普通账号」 小标签(管理员则是「管理员」)—— 不确定自己是什么权限时看一眼这里。

卡片上的「我的积分」只统计归属你本人的数据,别人账号的记录不会算进来。

导出我的全部数据

页头有一个「导出我的全部数据」按钮(也有单独一张卡片说明它在打包什么)。 点下去会下载一个 zip,里面是:

文件 内容
使用记录.csv 你全部的用量明细(不受页面筛选条件影响)
采集历史.csv 你的采集运行记录
操作审计.csv 你自己的操作审计(别人的看不到)
我的账号与配置.json 用户名 / 显示名 / 邮箱 / 角色 / 状态 / 本人的采集参数(只读项也在内)
说明.txt 各文件的口径说明

里面没有 Cookie 明文。 导出自己的数据不等于把凭证交出去 —— 凭证是密文入库的, 导出接口不碰它。需要迁移凭证就在新环境重新粘一次。

这个动作有 10 秒的最小间隔(防止连点生成一堆大文件)。数据量很大时 服务端是边生成边下发的,浏览器会先等一下再开始下载。

想留在系统里、由运维统一保管的那种备份(含所有人的数据),那是「备份管理」页的事, 只有管理员能做。你的 zip 只包含你自己。


十一、管理员专属功能

普通账号可以跳过这一章 —— 里面的入口你都看不到(导航里不显示,直接敲地址返回 403)。

11.1 调度与采集参数(在「任务管理 / 配置管理」里改)

管理员在这两页看到的是可编辑表单,改动是实例级的,对所有账号生效:

项 默认 说明
启用调度 开 总开关。关掉后只有手动采集会跑(注意:自动备份也一起停,见 11.5)
每日时刻 09:00,17:00 逗号分隔的本地时刻。保存即生效,不用重启
每日时刻上限 6 最多允许几个时刻(上限 12,代码硬顶)。时刻数直接决定采集频次
启动补跑 开 启动时把今天已错过、且还在宽限期内的时刻补采一次
补跑宽限期 12 小时 超过多少小时就不补了
采集最小间隔 60 秒 同一账号两次手动采集之间的最小间隔
单次最长跨度 31 天 一次采集最多覆盖多少天(硬顶 31 = 1 个月,改大也没用)
采集参数 见 9.2 分页 / 回退 / 超时 / 截断 / 证书校验等

⚠️ 改 schedule_times 会清理槽位簿记:系统只清掉「不再存在的时刻」对应的 槽位标记(所有账号一起清),不做全清 —— 全清会让全部账号在宽限期内一起重采。

⚠️ 把「每日时刻上限」调小时,超出上限的那几个时刻会被一并清掉(这是有意的: 上限本身就是刹车,留着超限的配置只会让人以为它还生效)。

11.2 实例级设置

「配置管理」页最下方,改动对所有账号生效:

设置 默认 说明
开放自助注册 允许 关掉后登录页不再显示「自助注册」,只能由管理员建号
同 IP 每日注册上限 3 防止一个来源批量刷号;范围 1 ~ 50
验证码策略 始终要求 始终要求 / 仅连续失败 2 次后要求 / 关闭
验证码位数 4 4 ~ 6 位

验证码策略怎么选:默认的「始终要求」最安全;「仅连续失败后要求」对天天登录的人 更友好,但会给机器人留出 2 次免验证码的尝试机会。「关闭」只有在前面已经有 可信网关时才考虑。

验证码的答案只存在服务端 captchas 表里,5 分钟过期、用一次就删 —— 所以它不会随会话 Cookie 泄漏出去。

自动备份的三个设置(开关 / 周期 / 保留份数)不在这里,它们有自己的页面, 见 11.5 备份管理页。

11.3 日志管理页

日志管理页

三个区块:

  1. 采集运行历史(可翻页 + 按状态筛 ok / warn / error / running) —— 每行可展开看逐行日志原文,排错时最有用的一块;表格里多了「账号」列, 能看出是哪个人触发的。
  2. 应用日志尾部 —— Web 进程自身的日志(启动、异常栈、调度动作)。
  3. 操作审计 —— 谁在什么时候做了什么:登录、登录失败、改配置、触发采集、导出、 建号删号、注册……

这是全实例视角(不是只你自己的)。普通账号访问本页返回 403, 所以管理员可以放心把这里当排错入口。

排错顺序建议:操作审计(有没有人动过)→ 采集历史(采集本身成不成功)→ 应用日志(程序有没有异常)。

11.4 用户管理页

用户管理页

操作 说明
新建账号 填用户名 / 显示名 / 邮箱 / 密码 / 权限(默认普通账号)
改显示名 行内直接改,点该行「保存」生效
改权限 管理员 ↔ 普通
改状态 启用 ↔ 停用(停用立即生效,不必等会话过期)
改密码 给忘了密码的同事重置。重置后他在所有设备上的登录立刻失效,需重新登录
删除 不可逆,会连同该账号的用量数据与 Cookie 一起删除

列表还给出每个账号的记录条数 / 积分合计 / 最后登录时间与 IP —— 但看不到内容: 管理员能看到的只是「有多少」,看不到「是什么」,也看不到任何人的 Cookie。

内置四条护栏(前端置灰 + 后端再拦一次):

  1. 不能取消自己的管理员身份(防止把自己锁在门外);
  2. 不能停用自己;
  3. 不能删除自己;
  4. 不能删掉最后一个启用的管理员(防止系统变成没人能管)。

页面底部是「账号操作审计」:最近 20 条账号相关动作,含注册与登录失败记录 —— 想知道有没有人在撞密码,看这里。

给同事开账号时默认选「普通」:管理员是能停用别人账号的角色,没必要扩大。

11.5 备份管理页

备份管理页

这一页只有管理员能看到(普通账号导航里没有,直接敲 /backups 返回 403)。 理由很实际:能下载或恢复整个数据库的人,等于对全库数据有完整的读写权。

顶部四张 KPI:现有份数 / 占用空间 / 自动备份开关 / 上次与下次自动备份时间。

自动备份设置(实例级,改完即生效):

设置 默认 说明
开启自动备份 开 关掉后调度线程不再打新快照(已有的不会删)
备份周期 24 小时 1 ~ 720 小时。到期就打一份,有采集在跑时跳过,等下轮
保留份数 7 超出的按时间删最旧的。只按磁盘上真实存在的文件算份数

备份列表:每行给出文件名、大小、记录条数、积分、来源(自动 / 手动 / 命令行 / 恢复前的自动快照)、生成时间,以及三个按钮:

按钮 做什么
下载 把 zip 存到本地。归档里含 instance.json,也就是全库的加密主密钥,所以它本身就是最高机密 —— 别放进公开网盘、别随手发人
恢复 把这份归档灌回数据库。会先弹两次确认(第二次专门问「是否连密钥一起回滚」)
删除 删掉这一份(文件 + 索引行)

「恢复」究竟做了什么(要点)

  1. 先校验这份归档能不能用;验不过就一个字节都不动。
  2. 自动给当前库打一份快照(来源标 pre-restore)—— 恢复错了还能回去。
  3. 整表替换记录 / 配置 / 账号等数据(在一个事务里,中途失败自动回滚)。
  4. 可选把归档里的密钥文件一起覆盖回来。
  5. 让所有人的登录立即失效 —— 恢复是全局性事件,旧会话描述的账号与权限 可能已经整个被换掉了。

几个常见疑问

  • 归档是怎么来的? 不是 cp 出来的。走的是 SQLite 官方在线备份 API, 按页复制并持有读事务 —— 采集正在写的时候拿到的也是一个完整一致的库。 直接拷文件可能缺最近一段数据,而且不报错。
  • 为什么归档里要带密钥? 不带的话,恢复出来的库里所有账号的 Cookie 都会 变成「无法解密」,等于把大家的凭证弄丢。所以默认带上;不想带就在恢复时选「否」。
  • 备份留在同一台机器上算备份吗? 只算一半 —— 它防的是「改错了」, 防不了「机器没了」。请定期点「下载」把归档拿到别的地方去, 异地那一份是这套机制替不了你的部分。
  • 磁盘占用怎么办? 「保留份数」会自动清理。也可以手动点删除, 或跑 python manage.py backups --prune --keep 5。

十二、信息安全与隐私安全

这一章讲清「系统为你做了什么」和「你该做什么」。前者是设计保证,后者只有你能做到。

12.1 系统为你做的(不需要你操心)

凭证(Cookie)的保护

措施 效果
ChaCha20 + HMAC-SHA256 encrypt-then-MAC 静态加密 数据库文件被拷走也读不出明文;被篡改会解密失败而不是返回垃圾
加密主密钥与数据库分开放 主密钥在 data/instance.json,与 usage.sqlite 不同文件;只拿到库 = 解不开
加密主密钥与会话签名密钥分键位 轮换其中一个不会影响另一个(混用会导致「想换会话密钥却把所有 Cookie 弄坏」)
页面 / 接口永不回传明文 只回「长度 + 结尾 4 位」;get_settings() 对加密键一律置空
凭证不参与实例级回落 NO_FALLBACK_KEYS = {cookie, user_agent} —— 回落等于「用别人的身份采集」,是最严重的一类越权
明文取用只有一条通道 db.get_secret(),只在真正发采集请求时调用

账号与访问控制

措施 效果
密码只存哈希 不存明文;管理员也不知道你的密码
登录失败双维度限速 同 IP、同用户名各自计数,任一连错 5 次锁定 10 分钟
先验验证码再比口令 否则攻击者能拿「密码对不对」当信号,提前跑完字典
验证码答案只在服务端 浏览器只拿一个随机 id,网页源码里搜不到答案
会话 Cookie 加固 HttpOnly(JS 读不到)+ SameSite=Lax(防跨站携带)+ 可选 Secure
停用立即失效 每个请求都回查账号状态,不必等 12 小时会话过期
写请求需 CSRF 令牌 防「登录状态下被别人页面静默提交表单」
安全响应头 CSP / X-Frame-Options / nosniff / Referrer-Policy
敏感接口 no-store /api/* 与 /captcha* 不会被浏览器或中间层缓存

数据隔离

措施 效果
全链路按 user_id 过滤 查询、采集、调度、导出都带 uid 参数
uid 是必填位置参数 代码里漏传就直接 TypeError,不会静默退化成「返回全量」
索引以 user_id 打头 隔离既是安全边界,也是查询性能的前提
越权写整单拒绝 普通账号提交只读项会被点名拒掉,不会「部分生效」

12.2 你要做的(系统替不了)

① 自己的 Cookie 自己填,不要经手别人。

Cookie 等于账号凭证。让同事代填 = 你的账号交到别人手里。 管理员也看不到你的 Cookie,所以没有任何人需要知道它。

② 不要在公共机器上保留登录态。

系统会话保持 12 小时。借别人的电脑用完就走右上角「退出」, 别只关标签页(会话在服务端仍然有效)。

③ 密码别和其他系统复用。

本系统没有邮件通道,忘密码只能找管理员重置,所以请用密码管理器记好。

④ Cookie 会过期,这是好事。

Cookie 通常随浏览器会话失效。过期后重新按 4.2 取一份即可, 历史数据完全不受影响。

⑤ 导出 CSV 后注意存放。

导出的 CSV 里有你的 Prompt 原文 —— 那是你真实的提问内容,可能包含代码、业务描述 甚至敏感信息。别随手丢在共享目录或聊天群里。用完删掉。

⑥ 管理员注意:备份要连密钥一起。

data/instance.json 里存着 Cookie 的加密主密钥。只备份 usage.sqlite 而不备它, 恢复后所有账号的 Cookie 都会变成「无法解密」,每个人都要重填一遍。 (反过来这也说明:这个文件本身就是高价值目标,权限要收紧。)

12.3 边界说明(诚实的那部分)

  • 管理员在运维层面能看到比你想象中多的东西:整机应用日志、所有人账号的 「记录条数与积分合计」、以及部署机器上的数据库文件本身。 管理员看不到你的 Cookie 明文、看不到你的 Prompt 内容、也看不到别人的记录内容 —— 但如果管理员对部署机器有 root 权限,理论上能改代码来绕过界面限制。 这是所有自托管系统的共同前提:信任部署这台机器的人。 所以如果是团队共用,请让「能登服务器」和「日常使用」的角色分开。
  • 传输加密取决于你的部署方式:纯局域网 http:// 部署下,流量在网内是明文的。 要防中间人,需要按 部署指南第六节 挂 HTTPS 反代, 并把 WB_COOKIE_SECURE 设为 1。
  • 系统不做数据自动清理:累积的记录会一直留着。要清理只能在数据库层面做, 属于管理员操作。

十三、常见任务速查

我想… 怎么做
自己注册一个账号 登录页 → 自助注册(需管理员开放注册)
配好我的采集 配置管理 → 我的云端凭证 → 粘贴 Cookie → 保存 → 任务管理「立即采集一次」
立刻采集一次 任务管理 → 立即采集一次(只采我自己的)
回补某几天的数据 任务管理 → 按区间补采,填起止日期
换我自己的 Cookie 配置管理 → 我的云端凭证 → 粘贴新 Cookie → 保存 → 回补最近几天
改我的显示名 / 邮箱 / 密码 右上角点自己的名字 → 个人中心
看清我是什么权限 看顶栏右侧的标签:「管理员」还是「普通账号」
查我自己的采集有没有成功 任务管理 → 运行历史(只有我自己的)
看清验证码 点验证码图片换一张
导出某段时间的数据给别人 数据明细 → 选日期 → 导出 CSV
导出我的全量存档 配置管理 → 维护动作 → 导出我的 CSV
找出最贵的请求 用量大屏 → 单笔 TOP
看某条请求的完整 Prompt 数据明细 → 该行「展开」
改采集时刻 ❌ 普通账号只读。找管理员改(或说明需求由他统一设)
看日志排错 ❌ 普通账号无权限。先用「任务管理 → 运行历史」,不够就找管理员
关掉自动采集 ❌ 普通账号无权限。找管理员
系统变慢了 找管理员做「配置管理 → 整理数据库」;再不行看下一章
把数据备份走 找运维按 部署指南第八节 备份,或自己导出 CSV
给同事开账号 管理员:用户管理 → 新建账号,权限选普通(或让同事自助注册)
同事忘记密码 管理员:用户管理 → 该行「改密」
临时封掉某个账号 管理员:用户管理 → 该行「停用」(数据与 Cookie 保留)

十四、常见问题

验证码看不清

点验证码图片换一张,不限次数、不消耗额度。图上刻意去掉了 0 O 1 I L 这几个易混字符, 只剩数字与不含它们的字母。也可以让管理员把「验证码位数」调成 4 位。

验证码明明填对了,还是提示错误

三种可能,按顺序排查:

  1. 这张图已经用过了 —— 验证码是一次性的,输错一次、或登录成功之后它立刻作废, 必须点图片重新取一张;
  2. 超过了 5 分钟 —— 有效期只有 5 分钟,换一张即可;
  3. 跨了页面 —— 登录页取到的图不能拿去注册页用(两边的验证码是分开的)。

另外:如果这个来源已被锁定(连续失败 5 次),即使验证码正确也会被拒;等 10 分钟再试。

登录页看不到「自助注册」

说明管理员把注册关掉了。两条路:请管理员在「配置管理 → 实例级设置」里打开, 或直接请管理员在「用户管理」里给你建一个账号。

注册被拒,说来源已达上限

同一个 IP 每天默认最多注册 3 个账号。换个网络,或请管理员把 「同 IP 每日注册上限」调大(范围 1 ~ 50)。

我为什么改不了定时任务 / 看不到日志

这是设计如此,不是权限配错了。 注册出来的账号一律是普通账号, 它只能维护本人的 Cookie / User-Agent,然后查看本人的数据。

你想要的 实际可行的
改采集时刻 ❌ 找管理员改(整机一套策略)
改采集参数 ❌ 把需求告诉管理员
看日志排错 先用「任务管理 → 运行历史」;需要逐行日志时找管理员
立刻采一次 ✅ 「任务管理 → 立即采集一次」,随时可用

如果你确实需要管理员权限(比如要做整库维护),请让管理员在 「用户管理」里把你的权限改成管理员。

采集一直没跑(我的数据没更新)

按这个顺序查:

  1. 你配 Cookie 了吗 —— 「配置管理 → 我的云端凭证」是否显示「已配置」。 没配的话采集到点会跳过你,运行历史里会有一条 no_cookie;
  2. Cookie 过期了吗 —— 运行历史里若有 cookie_expired / 401,按 4.2 重新取一份;
  3. 调度开着吗 —— 概览页「调度状态」看开关。关着的话就只有手动采集会跑;
  4. 服务是不是停了 —— 问管理员。调度线程在服务端进程里,服务停了就不采。

采不到也不慌:修好后用「按区间补采」把那几天补回来就行(重扫不会产生重复)。

「配置管理 → 我的云端凭证」出现红字横幅,或卡片上写着 无法解密:这是说数据库里 存的 Cookie 密文,用当前的实例主密钥解不开了。常见原因是 data/instance.json (里面存着 cookie_key)被删除、被替换,或者从别的机器拷了一份数据库过来。

影响:你这个账号的采集会失败,运行历史里是 cookie_broken。

怎么办:重新粘贴一次你自己的 Cookie 即可,历史数据不受影响。 (这个操作只有你本人能做 —— 别人看不到你的 Cookie,也就没法替你恢复。)

怎么避免:这是运维的事 —— 备份数据库时要把 instance.json 一起备份, 并且不要在容器之间混用。

我能不能看别人的用量

不能,管理员也不能。「用户管理」页只显示每个账号的记录条数与积分合计,看不到内容。 这是设计如此:Cookie 是账号级凭证,让它跨账号可见等于把别人的账号交出去。

如果团队确实需要合并统计,正确做法是每个人各自导出 CSV,再在外部合并。

Cookie 过期。重新按 4.2 拿一份新 Cookie 填进去。 Cookie 有效期通常是浏览器会话级别,关掉浏览器可能就失效了 —— 建议从已登录的 浏览器里复制时,勾选「保持登录」。

采集成功但「新增 0 条」

大概率是正常的:断点续采意味着没有新请求时确实没有新增。 看运行历史里那一次的 抓取 条数:

  • 抓取 > 0,新增 = 0 → 云端返回的都是库里已存在的,正常;
  • 抓取 = 0 → 该时段云端确实没有记录。

日期看起来差一天

所有日期都按部署机器的本地时区(容器里由 TZ 决定,默认 Asia/Shanghai)计算。 如果服务器时区不是东八区,跨日的数据会落到相邻日期上。 这属于部署问题 —— 找管理员确认 TZ=Asia/Shanghai(Docker)或系统时区(裸机)。

导出的 CSV 在 Excel 里中文乱码

不会 —— 导出已经带 UTF-8 BOM。如果乱码,先确认你打开的是本系统导出的文件, 而不是手工用记事本另存过的版本。

提示「采集正在进行中」

同一时刻只允许一个采集(SQLite 单写者)。等当前这次跑完再操作, 在「任务管理 → 运行历史」里能看到它是否还在 running。

页面能打开但图表空白

  1. 强制刷新(Ctrl+F5)清掉旧缓存;
  2. 检查浏览器控制台有没有资源 404;
  3. 找管理员看应用日志有没有异常栈(你这边看不到日志页)。

关掉浏览器后调度还在跑吗

在的。调度在服务端进程里,和浏览器无关。它是整机一套的, 所以你关不关浏览器都不影响它 —— 也正因为如此,它不归你管。

忘记密码

你自己忘了:网页上没法自助重置(没有邮件通道),找管理员在 「用户管理 → 该行『改密』」给你设一个新的。

管理员忘了(或者被自己停用了),到部署机器上执行:

python manage.py passwd admin 新密码                    # 裸机
docker compose exec portal python manage.py passwd admin 新密码   # Docker

# 顺便把被停用的账号恢复启用
python manage.py passwd admin 新密码 --activate
# 需要新建一个管理员
python manage.py passwd alice 密码 --role admin

想看现在都有哪些账号、各自什么角色与状态,用:

python manage.py users

数据会丢吗

正本是 Docker 命名卷 workbuddy-portal_wb_data 里的 usage.sqlite(对应容器内 /app/data)。 docker compose down 不会删数据;只有显式 docker compose down -v 或手动 docker volume rm 才会。备份方法见 部署指南第八节 —— 对使用者的日常来说,更简单的做法是 「配置管理 → 维护动作 → 导出我的 CSV」留一份快照。

能不能同时开多个采集进程

不能,也没必要。SQLite 单写者 + 文件锁的设计就是为了避免并发写。 真要跑多副本,除第一份外都要设 WB_DISABLE_SCHEDULER=1, 且只有一份能安全写 —— 所以不要横向扩展这个服务。


更多技术细节见 架构与设计说明、部署与运维指南、 接口参考、安全说明。