news 2026/9/28 21:41:16

Cap Checkpoint Middleware: Building a Cloudflare-Style Browser Check with Self-Hosted Proof-of-Work

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cap Checkpoint Middleware: Building a Cloudflare-Style Browser Check with Self-Hosted Proof-of-Work
  • 网络安全
  • 应用安全
  • 后端

【免费下载链接】cap

Free, open-source and self-hosted CAPTCHA alternative to reCAPTCHA. Privacy-first and powered by proof-of-work and instrumentation challenges.

项目地址:https://gitcode.com/gh_mirrors/cap13/cap
点击查看免费下载

Cap 的 Checkpoint(此前称为 middleware)是一套开箱即用的服务端中间件,用于复刻 Cloudflare 的"浏览器检查过渡页"(browser check interstitial):在请求到达你的真实业务路由之前,先要求浏览器完成一次自托管、开源的工作量证明(proof-of-work)CAPTCHA,从而把 bot、LLM 与自动化滥用挡在网站之外。本文以仓库中 docs/th/guide/middleware/index.md(其英文原版见 docs/guide/middleware/index.md)为核心骨架,结合 Cap Standalone 服务端源码,讲解 Checkpoint 的工作机制,并给出 Express、Hono、Elysia 三个框架的完整接入代码与全部配置参数,帮助你在一行行代码中落地自己的"核弹级"反机器人防线。

什么是 Cap Checkpoint

Checkpoint 是 Cap 生态中与 独立服务端(Cap Standalone) 配合使用的一组中间件包。它解决的核心问题是:在 bot、LLM 爬取和自动化滥用真正触达你的业务接口之前,先拦截它们。其效果等价于把整个网站搬到 Cloudflare 之后由 Cloudflare 免费附带的浏览器质询,但实现方式完全不同——你不需要迁移任何基础设施,只需在自己的服务器上引入几行代码。

与直接把整个网站托管给 Cloudflare 相比,Checkpoint 的优势非常直观:

  • 改动极小:不涉及 DNS、CDN 或全站迁移,只在应用服务中加入一个中间件;
  • 完全自托管:挑战的生成、验证、token 存储全部运行在你的服务器(或你自己的 Cap Standalone 实例)上,数据与策略都掌握在自己手中;
  • 开源透明:挑战算法与验证逻辑来自仓库中的 standalone/src/cap.js 等可审计代码。

不过,官方文档也给出了一条非常重要的提醒:这是一种"核弹级"(nuclear)方案——因为它面向的是"真实浏览器 + 人类用户"这一假设,搜索引擎爬虫、价格监控脚本、各类合法自动化工具同样会被挡在门外。如果你的站点依赖搜索引擎自然流量,部署前必须评估其对 SEO 的冲击。

Checkpoint 的工作链路

要正确使用 Checkpoint,先理解它站在 Cap 服务端能力之上的完整请求链路会很有帮助。从 standalone/src/cap.js 的源码结构看,一次完整的 Checkpoint 交互大致分为四个阶段:

  1. Challenge 签发:浏览器(或隐藏的 solver)向 Cap Standalone 的 challenge 接口请求一个待求解的工作量证明挑战。源码在签发时按 site key 的协议配置选择三种算法之一(standalone/src/cap.js):

    • sha256-pow:经典 SHA-256 工作量证明,可用challengeCount(默认 80)、saltSize(默认 32)、difficulty(默认 4)调节强度;
    • rsw:基于 RSW 时间锁谜题,通过rswT(默认 75_000 ms,允许 10_000–300_000 ms 区间)控制耗时;
    • hashwx:哈希工作量证明,通过hashwxDifficulty(默认 1_000_000,允许 50_000–5_000_000 区间)控制难度。

    每次签发的挑战都带有expiresMs: CHALLENGE_TTL_MS,源码中定义挑战有效期CHALLENGE_TTL_MS = 15 * 60 * 1000(15 分钟,standalone/src/cap.js),并写入scope: params.siteKey以绑定站点。

  2. 浏览器求解:Checkpoint 中间件的过渡页模板中必须包含 Cap 的 widget 或隐藏 solver,且指向/__cap_clearance这个 URL(Elysia 版文档的 NOTE 对此有明确要求)。求解完成后,前端把token与solutions提交给服务端的 redeem 接口。

  3. Redeem 验证与 token 签发:服务端调用核心库的coreValidateChallenge做密码学校验(standalone/src/cap.js),包括:

    • consumeNonce:用SET ... NX EX把已用过的签名写入blocklist:键,防止重放攻击;
    • signToken:生成siteKey:redeemId:redeemSecret三段式票据;
    • 校验通过后,把票据以token:前缀写入存储并设置EX过期(standalone/src/cap.js),服务端定义TOKEN_TTL_MS = 2 * 60 * 60 * 1000(2 小时,standalone/src/cap.js)。

    这一阶段还会处理多种失败原因:expired(挑战过期)、scope_mismatch(挑战 token 与 site key 不匹配)、already_redeemed(重复兑换)、以及 instrumentation 相关的一族错误(instr_corrupted、instr_expired、instr_automated_browser、instr_timeout、instr_missing,见 standalone/src/cap.js)——后者正是 Cap 的"instrumentation 挑战"能力:通过检测自动化浏览器行为大幅抬高 bot 门槛。

  4. Siteverify 放行:用户完成挑战并拿到合法 token 后,你的业务后端在信任其请求之前,向 Cap Standalone 的/siteverify端点做一次服务端验证(standalone/src/siteverify.js)。验证逻辑包含:校验secret与 site key 的对应关系(verifySecret,并自动把旧版密码 KDF 哈希升级为 SHA-256)、校验 token 三段式格式、用GETDEL一次性消费 token(防止同一 token 被重复使用)、检查过期时间(standalone/src/siteverify.js)。验证成功返回{ "success": true }。

Checkpoint 中间件正是把"第 2 阶段"的过渡页和放行逻辑封装成了对业务代码几乎零侵入的插件。

接入前置条件

在向 Express / Hono / Elysia 添加 Checkpoint 之前,请确认以下两件事就绪:

  1. Cap Standalone 后端可访问:Checkpoint 需要依赖 Cap 的 challenge / redeem / siteverify 能力,因此先按 standalone 部署指南 用 Docker 起一个实例(docker compose up -d),在管理面板创建 site key,记录 site key 与 secret key。注意实例必须能被公网访问,widget 才能与它通信。

  2. 准备过渡页模板:Checkpoint 的verification_template_path指向一个 HTML 模板文件。官方文档强调:模板只需要包含一个指向/__cap_clearanceURL 的 widget 或隐藏 solver即可,其余页面样式完全由你决定。也就是说,你可以把这个过渡页做成与站点一致的白标页面。

在 Express 中接入 Checkpoint

Express 版使用官方包@cap.js/checkpoint-express,配套cookie-parser管理放行 cookie。安装命令(docs/th/guide/middleware/express.md):

bun add express cookie-parser @cap.js/checkpoint-express

接入示例:

import express from "express"; import cookieParser from "cookie-parser"; import path from "path"; import { dirname } from "path"; import { fileURLToPath } from "url"; import { capCheckpoint } from "@cap.js/checkpoint-express"; const app = express(); const __dirname = dirname(fileURLToPath(import.meta.url)); app.use(express.json()); app.use(cookieParser()); app.use( capCheckpoint({ /* token_validity_hours: 32, tokens_store_path: ".data/tokensList.json", token_size: 16, verification_template_path: join(__dirname, "./index.html"), */ }), ); app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "success.html")); }); app.listen(3000, () => { console.log(`Server running on http://localhost:3000`); });

要点说明:

  • app.use(capCheckpoint({ ... }))注册在业务路由之前,因此所有后续路由都默认受到保护;如果你只想保护部分接口,可以把它挂在特定路径前缀上;
  • 注释块中的四个参数为可选配置:取消注释即启用自定义值(默认值见下文参数表);
  • 通过校验的浏览器拿到放行 cookie,之后请求可直接通过,无需反复解题;
  • 根路由返回success.html,即用户完成检查后进入的真实页面。

在 Hono 中接入 Checkpoint

Hono 版使用@cap.js/checkpoint-hono,用app.use("*", capCheckpoint(...))全局挂载,适合 Bun 上的轻量 Hono 应用(docs/th/guide/middleware/hono.md):

bun add hono @cap.js/checkpoint-hono
import { Hono } from "hono"; import { serveStatic } from "hono/bun"; import { capCheckpoint } from "@cap.js/checkpoint-hono"; const app = new Hono(); app.use( "*", capCheckpoint({ token_validity_hours: 32, // token 有效时长(小时) tokens_store_path: ".data/tokensList.json", token_size: 16, // token 大小(字节) verification_template_path: join(dirname(fileURLToPath(import.meta.url)), "./index.html"), }), ); app.get("/", (c) => c.text("Hello Hono!")); export default app;

这段示例把四个可选参数全部显式配置出来:token_validity_hours决定签发 token 的有效时长,tokens_store_path指定已签发 token 的持久化文件位置,token_size指定 token 的字节长度,verification_template_path指向你的过渡页模板。

在 Elysia 中接入 Checkpoint

Elysia 版使用@cap.js/middleware-elysia,示例还额外展示了scoping参数(docs/th/guide/middleware/elysia.md):

bun add elysia @cap.js/middleware-elysia
import { Elysia, file } from "elysia"; import { capMiddleware } from "@cap.js/middleware-elysia"; new Elysia() .use( capMiddleware({ token_validity_hours: 32, // token 有效时长(小时) tokens_store_path: ".data/tokensList.json", token_size: 16, // token 大小(字节) verification_template_path: join(dirname(fileURLToPath(import.meta.url)), "./index.html"), scoping: "scoped", // 'global' | 'scoped' }), ) .get("/", () => "Hello Elysia!") .listen(3000);

[!NOTE] 过渡页模板只需要包含一个指向/__cap_clearanceURL 的 widget 或隐藏 solver 即可正常工作,你可以在该模板中自由设计页面外观。

scoping允许"scoped"或"global":作用域控制 token 是限定在单个站点上下文还是全局有效。这一概念与 Cap 服务端的管理面设计相呼应——例如 standalone/src/server.js 中的scopeGuard会把 API key 的权限限定到特定 site key,只读 key 还会拒绝非 GET/HEAD 请求;同理,scoped 的挑战 token 也会在 redeem 阶段被scope_mismatch校验拦下(standalone/src/cap.js),确保一个站点签发的 token 无法被用于另一个站点。

Checkpoint 配置参数速查

综合三个框架的官方示例,Checkpoint 中间件的配置参数如下:

参数示例值含义
token_validity_hours32放行 token 的有效时长(小时),到期后浏览器需重新完成检查
tokens_store_path".data/tokensList.json"已签发 token 的持久化存储文件路径,用于服务重启后仍可校验
token_size16生成 token 的字节大小,影响 token 的随机强度
verification_template_pathjoin(__dirname, "./index.html")浏览器检查过渡页模板的绝对/相对路径;模板须包含指向/__cap_clearance的 widget 或隐藏 solver
scoping(仅 Elysia 版)"scoped"token 作用域,可选'global'或'scoped'

需要说明的是:中间件层面签发的放行 token 生命周期由token_validity_hours控制;而 Cap Standalone 服务端对 challenge 与 redeem 票据分别内置了 15 分钟挑战有效期与 2 小时 token 有效期(见 standalone/src/cap.js),两层生命周期相互独立、共同构成防线。

部署注意事项

  • 对善意的 bot 同样生效:Checkpoint 无法区分"坏 bot"和"好 bot",搜索引擎爬虫、RSS 抓取器、CI 健康检查等无头请求都会被要求解题。官方文档用"核弹级"来描述这一点,请结合业务对 SEO 和可访问性的要求决定是否全局启用。
  • 验证模板必须自持:每个框架的过渡页模板都要自带指向/__cap_clearance的 widget 或隐藏 solver,否则检查流程无法完成。
  • 前后端都要校验:中间件只负责前端放行;真正决定"是否信任"的是服务端对 token 的siteverify校验(一次性消费 + 过期检查,standalone/src/siteverify.js)。生产环境应在业务后端显式调用/siteverify,而不是只依赖 cookie。
  • 逆代与限流:如果你的实例在反向代理之后,请参照 standalone 配置指南 正确配置 IP 头与限流(源码中默认依次读取X-Forwarded-For、X-Real-IP、CF-Connecting-IP,见 standalone/src/cap.js)。

至此,你已经在三个主流框架中完成了 Cap Checkpoint 的接入。相比把整个站点交给 Cloudflare,这套方案把"浏览器检查"这一能力重新放回你自己的服务器与代码中:几行中间件代码、一个自托管后端,以及一份完全可控的 proof-of-work 防线。

  • 网络安全
  • 应用安全
  • 后端

【免费下载链接】cap

Free, open-source and self-hosted CAPTCHA alternative to reCAPTCHA. Privacy-first and powered by proof-of-work and instrumentation challenges.

项目地址:https://gitcode.com/gh_mirrors/cap13/cap
点击查看免费下载
上一篇:3 步 + 2 条红线:CodeWhale simplify 技能安全瘦身代码实战指南
下一篇:JavaScript事件循环终极指南:深入理解异步编程运行机制

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 21:39:50

高通诊断端口与QCN文件实操避坑指南

1. 这不是“改码教程”,而是一份高通平台底层通信的实操手记我干这行十年,修过上万台安卓设备,从早期的MTK联发科到后来的高通骁龙,再到如今的高通8系、7系平台,见过太多人拿着“改串码”当万能钥匙——结果没修好主板…

作者头像 李华
网站建设 2026/9/28 21:36:41

Python+MediaPipe实现AI健身评分系统:关节角度与动作质量量化

简介:这是一套基于Python搭建的AI健身评分系统实现资源,面向姿态估计、动作识别及运动分析方向的开发者与健身科技爱好者,可应用于体育训练辅助、动作规范检测等场景。项目以举哑铃动作为例,先提取人体关键点,再计算骨…

作者头像 李华
网站建设 2026/9/28 21:30:44

ASRPRO天问Block UART1与UART2串口通信配置与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 21:27:02

RT-Thread NUCLEO-STM32H563ZI BSP 快速上手与进阶开发指南

操作系统嵌入式物联网嵌入式OSRTOS 【免费下载链接】rt-thread RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/ 项目地址: https://gitcode.com/gh_mirrors/rt/rt-thread 点击查看 免费下载 本文以 …

作者头像 李华
网站建设 2026/9/28 21:26:47

Lap RAW+JPEG 配对机制详解:无损原片与压缩图从此不分离

Lap RAWJPEG 配对机制详解:无损原片与压缩图从此不分离 【免费下载链接】lap An offline-first photo manager for large local libraries 项目地址: https://gitcode.com/GitHub_Trending/lap3/lap Lap 是一款离线优先的本地照片管理工具,专为海…

作者头像 李华
网站建设 2026/9/28 21:26:37

大模型四域落地指南:视觉、NLP、语音与多模态的核心逻辑与实践

1. 全景概览:四个应用域背后的“同一套底层逻辑”聊大模型,很多人第一时间想到的是ChatGPT这类对话产品。但如果只盯着文本对话,你会发现根本解释不了“为什么同一种技术架构能识图、能听写、能翻译、能生成视频还能做情感分析”。实际上&…

作者头像 李华