当前,“人工智能+”服务千行百业。作为人工智能技术应用的最前端,大模型正在为产业发展提供有力支撑。在视频大模型应用赛道,国产大模型正在深度融入产业。视...
2025-09-01 0
A modern, lightning-quick PoW captcha
一种现代的、闪电般快速的工作量证明验证码
Cap is a lightweight, modern open-source CAPTCHA alternative using proof-of-work
Cap 是一款轻量级、现代化的开源验证码替代方案,采用工作量证明机制。
与传统验证码不同,Cap:
Cap 主要由小部件(可以以不可见的方式使用)和服务器(你也可以使用独立服务器)组成。另外,它还支持机器对机器通信,并且有一个类似于 Cloudflare 的检查点中间件。
#技术分享文档地址:capjs.js.org/
github:github.com/tiagorangel…
以在 Vue3 + ElementPlus 中使用为例
在 index.html 引入 Cap widget:
生产环境请引入固定版本
<script src="https://cdn.jsdelivr.net/npm/@cap.js/widget"></script>
在 ElForm 中使用组件:
<el-form-item prop="code"><cap-widget id="cap" :data-cap-api-endpoint="capApi" data-cap-i18n-verifying-label="验证中..." data-cap-i18n-initial-state="点击验证" data-cap-i18n-solved-label="验证通过" data-cap-i18n-error-label="验证失败,请重试" ></cap-widget></el-form-item>
其中 data-cap-api-endpoint 为服务端验证 URL 我这里设置为:
const capApi = ref(`${import.meta.env.VITE_API_URL}/admin/sys/login/`);
data-cap-i18n 开头的几个选项为国际化设置。
设置表单,以及校验规则:
import { type FormInstance, type FormRules } from "element-plus";const formRef = ref<FormInstance>();let formData = reactive< paths["/admin/sys/login"]["post"]["requestBody"]["content"]["application/json"]>({> username: "",> password: "",> code: "",> });const rules = reactive<FormRules<typeof formData>>({ username: [{ required: true, message: "请输入用户名" }], password: [{ required: true, message: "请输入密码" }], code: [{ required: true, message: "请点击验证" }], });
监听 Cap 校验结果:
onMounted(() => { const widget = document.querySelector("#cap");widget?.addEventListener("solve", function (e: any) { formData.code = e.detail.token; }); });
表单校验及提交不在赘述
以在 Nestjs 中使用为例
安装 @cap.js/server
npm i @cap.js/server
在 Service 中创建 Cap 实例:
import { InjectRepository } from "@nestjs/typeorm";import Cap from "@cap.js/server";@Injectable() export class LoginService { cap: Cap = new Cap({ tokens_store_path: ".data/tokensList.json" }); }
Cap 默认使用内存和文件存储 token,你可以将 noFSState 设置为 true ,仅使用内存存储 token。
你可以将此与设置 config.state 结合使用,以使用诸如 Redis 之类来存储令牌。
可以参考这个 Pull requests 。
在 Controller 中创建接口:
import { BadRequestException, Body, Controller, Post } from "@nestjs/common";import { LoginService } from "./login.service";@Controller("login") export class LoginController { constructor(private readonly loginService: LoginService) {}@Post("/challenge") async challenge() { return this.loginService.cap.createChallenge(); }@Post("/redeem") async redeem( @Body() body: { token: string; solutions: Array<[string, string, string]> } ) { const { token, solutions } = body; if (!token || !solutions) { return new BadRequestException("人机验证失败"); } return this.loginService.cap.redeemChallenge({ token, solutions }); } }
当用户点击客户端 Cap 组件时,将请求 /challenge 和 /redeem 获取 token。
最后在登录接口的 Service 内添加 token 验证:
const result = await this.cap.validateToken(loginDto.code);if (!result.success) { throw new BadRequestException("人机验证失败");}
如果你想看这篇文章内的详细代码,可以查看 foolon admin 的登录功能:
github:github.com/LLcci/foolo…
gitee:gitee.com/shangchehan…
如果你有任何想法,欢迎在评论区交流呀~
相关文章
当前,“人工智能+”服务千行百业。作为人工智能技术应用的最前端,大模型正在为产业发展提供有力支撑。在视频大模型应用赛道,国产大模型正在深度融入产业。视...
2025-09-01 0
您好:这款游戏可以开挂,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好牌,而且好像能看到-人的牌一样。所以很多小伙伴就怀疑这...
2025-09-01 0
8月29日,山西省地质勘查局内气氛热烈,备受瞩目的山西省地勘行业首家新型研发机构——山西地质科学研究院在此隆重揭牌。这一标志性事件,标志着山西省在地质...
2025-09-01 0
您好:这款游戏可以开挂,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好牌,而且好像能看到-人的牌一样。所以很多小伙伴就怀疑这...
2025-09-01 0
鞭牛士报道9月1日消息,位于河南郑州的同城跑腿公司UU跑腿在官方微信上指责淘宝闪购刚发布的骑士工服抄袭。UU跑腿是郑州时空隧道信息技术有限公司旗下同城...
2025-09-01 0
您好:这款游戏是可以开挂的,软件加微信【添加图中微信】确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好牌,而且好像能看到其他人...
2025-09-01 0
在电动车市场,小牛、九号虽热度颇高,但5000元以内价位中,仍有不少品牌凭借长续航与高性价比脱颖而出。今天推荐的5款车型,续航表现都很亮眼,最远可达2...
2025-09-01 0
发表评论