网络安全应用安全后端【免费下载链接】capFree, 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 是一个免费、开源、可自托管的 reCAPTCHA 替代方案其验证核心不是让用户点选图片或识别扭曲文字而是让浏览器在后台默默完成工作量证明proof-of-work质询。本文围绕仓库中的演示页面 docs/zh/guide/demo.md 展开先说明该页面如何以“评论表单”的形式让访客零配置体验整个验证闭环再深入剖析演示服务端 demo/index.js 的完整实现——从挑战签发、Nonce 防重放、令牌赎回到 widget 前端配置与浮动态模式最终给出本地一键运行演示的方法。读完本文你将掌握 Cap 演示的端到端工作链路并能在自己的机器上跑起同款演示环境。一、演示页面是什么一个内嵌在文档里的“活”验证组件docs/zh/guide/demo.md的 frontmatter 用一句话定义了它的主题“在线体验 Cap实时演示这个开源、自托管的 CAPTCHA 验证组件如何在你的浏览器中求解工作量证明质询无需点选任何视觉谜题。”与普通纯文字教程不同这份文档本质上是一个可交互的演示页页面上嵌入了几类 VitePress 组件占位符DemoTabs /用于切换不同的演示模式如普通模式与浮动态模式Demo /真正渲染cap-widget验证组件的挂载点文档通过内联样式--cap-widget-width: 300px限定演示组件的宽度DemoReply /在验证完成后展示“回复已发送”之类的反馈区域。页面还自带了一段完整的评论表单 CSS.login-form、.signin-button等样式用纯 CSS 模拟出一个真实评论框 提交按钮的交互外观文本框获得焦点时出现品牌色光环box-shadow: 0 0 0 .25rem rgba(38, 181, 250, .25)未激活的提交按钮呈灰度禁用态激活后带两次脉冲动画signin-button-pulse。这些样式全部内联在 Markdown 文档中意味着演示页在视觉上被刻意塑造成“发一条评论”的真实场景让访客在不知不觉中完成一次完整的 CAPTCHA 验证体验。页面最后一行明确标注了演示的边界“本演示使用的占位服务端不会执行 instrumentation浏览器环境检测。”这是理解演示能力范围的关键信息——文档页面上跑的是一个简化版后端只演示工作量证明质询的求解不演示 instrumentation 挑战的完整流程。二、演示体验流程从评论框到验证令牌演示页面的交互逻辑可以拆成三步与真实生产环境中的 Cap 验证闭环一致填写评论用户在仿评论表单的文本框中输入内容页面预置了示例文案“看起来很棒感谢分享”触发验证Demo /挂载的cap-widget组件向演示服务端的POST /api/challenge请求签发挑战随后在浏览器内借助 WASM 加速后台求解工作量证明质询全程无需点击任何图片、无需识别任何字符提交与反馈验证通过后组件抛出solve事件携带令牌DemoReply /区域给出完成反馈提交按钮从禁用态切换为激活态并播放脉冲动画。整个流程中用户与验证组件的交互负担被压缩到最低——这是 Cap 与 reCAPTCHA 类视觉谜题方案最核心的体验差异。下面我们从源码层面看演示服务端如何支撑这条链路。三、演示服务端实现解剖demo/index.js演示服务端基于ElysiaBun 生态的 Web 框架编写入口文件为 demo/index.js共约 130 行职责清晰可按功能分为四块。3.1 全局状态Secret、Nonce 与已赎回令牌const SECRET process.env.CAP_SECRET || randomBytes(32).toString(hex); const redeemed new Map(); const nonces new Map();SECRET用于签发/校验挑战的 JWT 密钥。演示模式未设置CAP_SECRET环境变量时会为每次进程启动随机生成 32 字节密钥——这直接导致重启服务后旧令牌全部失效仅适合演示场景生产环境则必须使用稳定、高熵的固定密钥见 core/src/index.js 对secret长度至少 16 字节的强制校验。redeemed与nonces是两个内存 Map分别记录已赎回令牌的过期时间与已消费 Nonce 的 TTL配合每 60 秒一次的定时清理.unref()不阻塞进程退出实现内存态防重放。3.2 静态资源与打包路由app.get(/cap.js, async ({ set }) { const main await fs.readFile(../widget/src/src/cap.js, utf-8); const worker await fs.readFile(../widget/src/src/worker.js, utf-8); const css await processCSS(); const bundle main .replace(%%workerScript%%, () JSON.stringify(worker)) .replace(%%capCSS%%, () css) .replace(%%i18nKeys%%, () i18nShippedKeys.join(,)) .replace(%%i18nData%%, () i18nJSON); ... });/直接返回index.html/cap.js在运行时完成 widget 源码的打包把 widget/src/src/cap.js 中的%%workerScript%%求解 worker、%%capCSS%%经 lightningcss以及%%i18nKeys%%/%%i18nData%%多语言文案来源 widget/src/src/i18n/translations.js等占位符逐一替换为真实内容/cap.css返回压缩后的组件样式/cap-floating.js直接透传浮动态入口 widget/src/src/cap-floating.js。也就是说演示页面引用的cap.js是从当前仓库的 widget 源码现场打包的任何 widget 改动都会即时反映在演示中。3.3 三个 API 端点完整的验证闭环演示服务端用三个端点复刻了 Cap 的生产验证流程端点方法职责/api/challengePOST调用generateChallenge(SECRET, { instrumentation: true })签发挑战/api/redeemPOST调用validateChallenge(SECRET, body, { consumeNonce })校验求解结果并发放令牌/api/validatePOST接收{ token }校验令牌是否已赎回且未过期/api/challenge的实现最简洁直接委托给 capjs-coreapp.post(/api/challenge, async () { return await generateChallenge(SECRET, { instrumentation: true, }); });注意这里instrumentation: true——虽然页面文案声明“占位服务端不会执行 instrumentation”但挑战签发端仍请求了 instrumentation 数据由 core/src/index.js 的generateChallenge通过generateInstrumentation生成并经encryptGcm加密进 JWT。结合演示注释可推断演示服务端签发了带 instrumentation 的挑战但占位服务端在校验侧并未真正执行对应的环境检测环节即验证只依赖工作量证明部分。/api/redeem则完整演示了防重放与令牌发放app.post(/api/redeem, async ({ body, set }) { if (!body || typeof body ! object) { set.status 400; return { success: false, reason: invalid_body }; } const result await validateChallenge(SECRET, body, { consumeNonce }); if (result.success) { redeemed.set(result.tokenKey, result.expires); ... } return result; });consumeNonce回调实现如下基于挑战令牌的签名哈希做 TTL 级去重const consumeNonce async (sigHex, ttlMs) { if (nonces.has(sigHex)) return false; nonces.set(sigHex, Date.now() ttlMs); return true; };这对应 core/src/index.js 中validateChallenge对opts.consumeNonce的调用约定同一挑战令牌只能赎回一次重复提交返回already_redeemed。/api/validate负责令牌二次核验——这模拟了生产环境中“前端拿到令牌后业务后端再向 Cap 服务端确认令牌有效”的场景const [id, secret] String(body.token).split(:); const tokenKey ${id}:${createHash(sha256).update(secret).digest(hex)}; const expires redeemed.get(tokenKey); if (!expires || expires Date.now()) return { success: false }; return { success: true, expires };令牌格式id:secret与validateChallenge成功路径的返回值一致core/src/index.js服务端只持久化id secret 的 SHA-256明文 secret 不下存储过期即失效。四、挑战生成与校验的底层参数capjs-core 默认值演示端点使用的generateChallenge/validateChallenge均来自capjs-core包demo/package.json 中声明依赖capjs-core: ^0.1.0其实现位于 core/src/index.js。演示未显式传参因此实际生效的是以下默认值参数默认值说明challengeCountc50单次挑战含 50 个子质询求解器需逐一完成challengeSizes32每个质询 salt 的长度字节challengeDifficultyd4工作量证明难度即哈希结果需匹配的前导零十六进制位数expiresMs10 * 60 * 100010 分钟挑战令牌 TTLtokenTtlMs20 * 60 * 100020 分钟成功验证后发放的令牌 TTL代码层面的取值范围约束core/src/index.jschallengeCount ≤ 1000、challengeSize ≤ 256、challengeDifficulty ∈ [1, 16]越界会直接抛错。验证侧会基于挑战 JWT 中的c/s/d参数逐项重算并比对 SHA-256 前缀匹配powMatchesPrefix确保求解结果真实有效。求解的核心逻辑是对每个质询以“令牌哈希 序号”派生盐与目标值服务端用prngFromHash生成确定性的 salt 与 target客户端提交数字解solutions[i]服务端计算sha256(salt solution)并校验其十六进制前缀是否命中 targetcore/src/index.js。这正是“无需视觉谜题、纯算力证明”的技术本质。五、前端 widget 配置demo/index.html里的真实用法演示页的 HTML 骨架在 demo/index.html 中它同时展示了普通模式与浮动态模式两种cap-widget用法cap-widget idcap onsolveconsole.log(Token: ${event.detail.token}) ># 安装依赖demo 与 widget 各自有独立的 bun.lock分别安装 bun install --cwd demo bun install --cwd widget bun install --cwd core # 启动演示服务 bun run --cwd demo start服务默认监听http://localhost:3000可通过环境变量调整PORT8080 bun run --cwd demo start # 修改端口 CAP_SECRET你的高熵密钥 bun run --cwd demo start # 使用固定密钥启动后浏览器访问首页即可获得与文档页一致的体验填写评论 → widget 在后台完成工作量证明 → 控制台打印Token: ...点击 “Trigger floating mode” 可切换浮动态组件。需要特别说明的适用前提与限制运行演示需要 Bun 运行时Node.js 直接执行index.js会因 Elysia 依赖与bun语法而不保证兼容演示的令牌存储redeemed/nonces均为进程内存态重启即失效仅适合本地体验如前文所述占位服务端的校验侧不真正执行 instrumentation 环境检测完整的 instrumentation 挑战含自动化浏览器拦截等需要在生产级部署如 standalone 或自行接入 capjs-core中验证。七、从演示到生产演示代码透露的落地要点演示服务端虽然只有一百余行却完整覆盖了生产接入的三件套值得作为最小可运行参考挑战签发与校验必须共享同一SECRET演示默认每次启动随机生成生产场景应使用固定密钥并在多实例间保持一致assertSecret强制 ≥ 16 字节防重放是刚需通过consumeNonce回调按签名哈希去重返回already_redeemed这是防止令牌被多次使用的基础设施令牌核验接口解耦/api/validate展示了“业务侧只存 tokenKey、不存明文”的令牌校验范式避免业务系统直接依赖挑战校验细节。将这三条迁移到自己的服务端就足以把 Cap 从“可玩”的演示推进到“可用”的接入状态。结语docs/zh/guide/demo.md表面上是一页交互演示背后却是一条完整的“挑战签发 → 浏览器求解 → 赎回令牌 → 业务核验”链路。本文结合 demo/index.js、demo/index.html 与 core/src/index.js 逐层还原了它的实现默认参数、Nonce 防重放、运行时打包、浮动态配置与本地启动方法全部有仓库源码可查。理解这套最小闭环之后无论是接入 widget、自建服务端还是阅读 docs/zh/guide/capjs-core.md 与 docs/zh/guide/server.md 做生产级部署你都将有一个直观的“工作模型”作为起点。赞分享网络安全应用安全后端【免费下载链接】capFree, 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 在线 Demo 全解析零视觉谜题的 proof-of-work CAPTCHA 演示与实现Cap 在线 Demo 全解析零视觉谜题的 proof of work CAPTCHA 演示与实现 本文围绕 Cap 开源仓库中 docs/fr/guide/网络安全应用安全后端Cap 在线演示Demo深度解析体验与复现免点击、基于工作量证明的 CAPTCHA 验证Cap 在线演示Demo深度解析体验与复现免点击、基于工作量证明的 CAPTCHA 验证 本文以仓库多语言文档中的 演示页泰语版 https://li网络安全应用安全后端PPTist在线演示工具重新定义浏览器中的PPT创作体验PPTist在线演示工具重新定义浏览器中的PPT创作体验 你是否曾经遇到过这样的困境急需制作一份专业PPT却发现电脑上没有安装PowerPoint或者想前端企业应用上一篇3种场景解锁微信数据价值WeChatMsg本地化备份工具全解析下一篇为ESP32智能设备赋予视觉能力xiaozhi-esp32摄像头集成实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
TypeScript 声明文件模板深度解析:为全局代码库编写 global.d.ts 文档教程 【免费下载链接】TypeScript TypeScript 使用手册(中文版)翻译。http://www.typescriptlang.org 项目地址: https://gitcode.com/gh_mirrors/typ/TypeScript 点击查看 免费下载 本文是 TypeScript 使用手册(中文版&… · 2026/9/28 3:09:13
编写 GenOffice 标准编辑操作文档:ops/_format.md 规范、OP_DOCS 解析与示例测试保障 人工智能AI 应用桌面应用AI AgentMCP 服务AI 技能 【免费下载链接】genoffice Free, open-source AI Office suite: Docs, Sheets, Slides, PDF, Markdown and HTML editors with a built-in AI agent, plus a genoffice CLI and agent skill so Claude Code, Codex and Cursor… · 2026/9/28 3:09:13
《机器学习训练秘籍》学习曲线进阶:如何解读高偏差、高方差与“偏差方差双高“三种典型形态 文档教程 【免费下载链接】machine-learning-yearning-cn Machine Learning Yearning 中文版 - 《机器学习训练秘籍》 - Andrew Ng 著 项目地址: https://gitcode.com/gh_mirrors/ma/machine-learning-yearning-cn 点击查看 免费下载 本文聚焦《Machine Learning Y… · 2026/9/28 3:09:13
Spingboot启动预热的实现 启动预热的适用场景启动预热适合以下情况:数据主要来自第三方接口,无法直接从本地数据库读取。第三方接口响应较慢,首次访问容易超时。一个页面需要调用多个第三方接口或逐项查询。数据读取频繁,但变化不频繁。希望服务启动后&… · 2026/9/28 3:40:12
学Java别走弯路,这5个方向最吃香 学Java的人很多,但学明白的人不多。有人学了半年还在写控制台程序,有人一年就能独当一面。差别不在天赋,而在方向。Java生态太庞大了,什么都学等于什么都没学。选对方向,事半功倍。今天盘点当前最吃香的5个Java方向&am… · 2026/9/28 3:32:15
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
制作网页比较方便的软件怎么选?一文搞懂避坑指南 制作网页比较方便的软件怎么选?一文搞懂避坑指南 很多老板一上来就问:做个网站多少钱?但我反问他:你的域名买了吗?服务器租了吗?他一脸懵。这就是典型的“域名服务器搞不懂”。别急,今天咱们不聊虚的,直接 一文搞懂 那些让你头秃的技术名词。… · 2026/9/28 0:00:06
婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 找婚恋网站建站公司,最怕的就是被坑高价。很多同行跟我吐槽,报价单上写得模棱两可,功能栏里全是“高级定制”、“专属UI”,结果落地全是套壳。今天不聊虚的,直接甩几个我经手的 实战案例… · 2026/9/28 0:00:19
济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 上周济南一个做建材的老板找我,脸都绿了。他的官网首页弹出了赌博广告,后台被植入了挖矿脚本。他慌得问我:“网站被黑挂马不知道怎么办?能不能直接找之前的外包公司要源码下载,看看哪里被动了手脚?… · 2026/9/28 0:00:25