前天中午莫名其妙收到一条评论:内容是英文的,昵称是印尼语(翻译过来是“混凝土板”),链接是拼凑的(一个东南亚中医诊所)。更诡异的是,评论发布在一篇已经被我隐藏的文章里。而昨天中午又在相近的时间、相同的文章收到了类似的评论。可惜两条评论脑子一热全给删了,没留着对IP做点“有意思”的分析,而是直接打为人机,也因此开始着手做评论区的反人机系统。
硬要说Typecho这框架还有什么优点,我个人认为是其完善的插件生态。尽管牺牲了一部分的自定义能力,这种“抄作业”模式确实让功能的添加与分离更便利了些。
从2000年 CAPTCHA (Completely Automated Public Turing test to tell Computer and Human Apart, 全自动区分人类与计算机的图灵测试)(又臭又长)以其经典的“识别扭曲字符串/图形分类”模式出现,到Google reCAPTCHA v1,v2 的“人工OCR”和 臭名昭著的“人工数据标注”,再到如今逐渐无操作化的reCAPTCHA v3(代价是跨站追踪构建你的用户画像)以及转而“拷打浏览器”的Cap,Turnstile等——人类在网络世界同自动机器的斗争从未停歇,当然这期间也收割了盟友无数免费的劳动力。
在2026年,想要让各位在发表评论前“标记下面图片中的红绿灯👇”无异于化身全民公敌,因此思路一定是要往无感化的方向靠拢的。找来找去,最终敲定了Cap。原因嘛……当然是因为其有 诸多优点 现成插件啦!
Cap,是啥?
首先简要介绍一下这种验证模式。Cap不仅如前所述选择“拷打浏览器”,还玩了招阴的——成本。两层的验证模式中,
- 第一层:工作量证明(PoW) 在这里,服务器会向发起请求的Cap组件生成一个“挑战”,要求请求端暴力算出一个与答案(通常是一个特定的模式,例如要求哈希值以
0000开头)匹配的SHA-256值。由于SHA-256用16进制表示,这意味着浏览器平均要做16^4=65536次尝试。对于只想发一条评论的你而言,这点功夫不值一提,而对于广告灌水的自动程序,这可是一笔相当不划算的算力开销。从成本考虑,这类CAPTCHA实在不值得大量“硬刚”——不得不说,这一招确实高明! - 第二层:浏览器验证 已经不算新鲜了。Cap服务器会向请求端发送一段随机的、只有浏览器端才能正确实现的JS程序,来确定请求来源。
Cap服务器会在两层验证均通过后,向客户端返回一个JWT redeem token。最后还有一步,客户端服务器(注意不是浏览器)需要将这个token和自己的SiteSecret字段再次发送给Cap服务器做一次检验,确保token有效,避免伪造/复用。
这是一个成功的Cap请求的时序图:
CAP请求流程图.png那么,它的优势在哪?可以归结为以下几点:
- 轻(客户端组件12-20KB),加载快。
- 注重隐私。不收集用户数据。
- 开源,可自托管(事实上自托管是最好的选择!)
只说优势不说劣势是不对的。其缺点主要是:
- 只防懒汉,不防行家。PoW只能让低成本自动化变得极不划算。如果有人铁了心要刷你的博客,甚至不惜买GPU集群,那么Cap也没办法。
- 如果攻击者用了无头浏览器,两层验证即可轻松通过。
插件:Cap for Typecho
项目地址:https://github.com/hzl0931/Cap_for_Typecho
基于 cc2562/Cap_for_Typecho 的插件再开发。原作者的老版插件在Typecho 1.3.0启动时会出Bug,已经做了修复。同时增加了使用 Cloudflare Access Service Token 保护 自托管Cap /api/validate/服务的功能(见下节)。
注意,在使用前,需要手动把前端逻辑业务逻辑写进你的评论表单文件(参见项目readme)。
对于不想使用国外客户端脚本(默认的https://captcha.gurl.eu.org/cap.min.js)的用户,可以选择国内CDN:https://cdn.jsdelivr.net/npm/@cap.js/[email protected]/cap.min.js。
托管你自己的Cap服务并保护
Cap默认的API服务由开发者个人通过https://captcha.gurl.eu.org/api/提供,国内可能不太稳定。你可以在Cap原项目地址找到自托管的方法。但是最方便的当然是使用Cloudflare!xyTom/cap-worker项目已经构建好了生产/开发环境,可以一键部署到Cloudflare。服务启动后,你会得到一个链接,类似于这样:
服务链接-Cloudflare Worker界面.png接下来只需将你的链接/api/填入插件设置中的“Cap API 端点”字段就可以使用了。如果你希望将域名整合到自己的固有域名中,可以点下方的“添加域名”或“添加路由”,但你需要把自己域名的DNS解析全部迁移到Cloudflare下。(Cf免费的域名解析还是很香的!)
保护你的/api/validate/
自己有一点一直没绕清楚。因为Cap服务的验证依赖SHA-256计算,因此如果你的服务地址(/api/challenge/ & /api/redeem/)暴露在公网,很有可能就会被别人拿去白嫖——但,这是没有办法的。Cap本身就要求对/api/challenge/的请求匿名,因此,用服务令牌一类的token机制保护/api/challenge/毫无意义。
唯一能保护的是/api/validate/接口。这个接口的目的是完成两层验证后对JWT redeem token的鉴定。为此,开通免费的Cloudflare Zero Trust基础版,在访问控制-服务凭据里新建服务令牌,再在访问控制-应用程序中新建“自托管/私有”程序,在目标-公共主机名中填自己的url(your-cap-server-url/api/validate/),在“Access 策略”中选择“Service Token”,“操作”选择“服务身份验证”,然后保存;回到插件设置,填入新建服务令牌时提供的Cloudflare Access Client ID和Client Secret,搞定!
千万不要试着也对/api/challenge/ & /api/redeem/添加同样的保护策略。牢记对/api/challenge/ & /api/redeem/的请求是匿名的,永远不会也不应该受到服务令牌保护。
我大概看了下目前主流的 SPAM 解决方案, 是越来越不计成本了, 主流的所有交互式人机验证都已有逆向, 通过精确的缺口识别和 Token 购买等方法, 先用无头浏览器之类的加载文章页模拟浏览, 拿到所有 JS 数据, 而后火速解析, 将最后的各种参数汇总后直接 POST 到后端接口, 有些厂商的 SPAM 还会在识别不到通用操作后调用 AI 分析页面然后学习, 大概也不会为着这点点计算成本考虑, 毕竟灰产投广告成功赚的钱是一笔大数目, 重点还是在内容审查和及时清理上
允许人类评论, 就需要把操作步骤交给客户端, AI 时代, 这不过是小菜一碟, 验证码只是阻挠了小体量, 技术不咋地的那些, 还有降低大量发布的可能性
受教🌹!确实。对于个站,人力审核最终还是最优解。