验证码
验证码插件
验证码插件通过在关键端点添加验证码验证,为您的 Better Auth 系统集成了机器人防护功能。此插件确保只有人类用户可以执行注册、登录或重置密码等操作。当前支持的提供者有:
安装
将插件添加到 auth 配置中
import { betterAuth } from "better-auth";
import { captcha } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
captcha({
provider: "cloudflare-turnstile", // 或者 google-recaptcha、hcaptcha、captchafox
secretKey: process.env.TURNSTILE_SECRET_KEY!,
}),
],
});为基于令牌的提供者发送令牌
现在不再需要 x-captcha-user-remote-ip 头 — IP 地址由服务端自动检测。
对于基于令牌的提供者,请在向受保护端点发送请求时添加验证码令牌。以下示例展示了一个 signIn 请求:
import { authClient } from "@/lib/auth-client"
await authClient.signIn.email({
email: "[email protected]",
password: "secure-password",
fetchOptions: {
headers: {
"x-captcha-response": turnstileToken,
},
},
});- 要在客户端实现 Cloudflare Turnstile,请参考官方 Cloudflare Turnstile 文档 或使用类似 react-turnstile 的库。
- 要在客户端实现 Google reCAPTCHA,请参考官方 Google reCAPTCHA 文档 或使用类似 react-google-recaptcha(v2)和 react-google-recaptcha-v3(v3)的库。
- 要在客户端实现 hCaptcha,请参考官方 hCaptcha 文档 或使用类似 @hcaptcha/react-hcaptcha 的库。
- 要在客户端实现 CaptchaFox,请参考官方 CaptchaFox 文档 或使用类似 @captchafox/react 的库。
提供者
Vercel BotID
BotID 需要 Vercel 部署和客户端设置。请按照 Vercel 的设置指南,根据您的框架配置重写规则并集成客户端。Better Auth 插件不使用 secretKey 或 x-captcha-response 头:
import { checkBotId } from "botid/server";
import { betterAuth } from "better-auth";
import { captcha } from "better-auth/plugins";
export const auth = betterAuth({
plugins: [
captcha({
provider: "vercel-botid",
checkBotId,
}),
],
});使用 initBotId 时,请在实际请求路径上保护 Better Auth 的默认身份验证路由:
import { initBotId } from "botid/client/core";
initBotId({
protect: [
{ path: "/api/auth/sign-up/email", method: "POST" },
{ path: "/api/auth/sign-in/email", method: "POST" },
{ path: "/api/auth/request-password-reset", method: "POST" },
],
});BotID 使用浏览器中的完整请求路径。插件的 endpoints 选项省略了 Better Auth 的基础路径,例如 /sign-in/email。如果更改 basePath 或 endpoints,请确保两者保持同步。
在浏览器中初始化 BotID 后,无需验证码令牌头即可正常登录:
import { authClient } from "@/lib/auth-client";
const { data, error } = await authClient.signIn.email({
email: "[email protected]",
password: "secure-password",
});BotID 不支持原生 HTML 表单提交。
本地开发默认允许请求,因此在正式环境中依赖它之前,请先在 Vercel 上验证完整流程。有关特定路由的检测级别,请参阅 Vercel 的高级配置。
工作原理
此插件充当中间件:它会拦截发往已配置端点的请求(请参阅插件选项部分中的 endpoints)。
它会通过调用验证码提供者的 /siteverify,在服务器上验证验证码令牌。
Vercel BotID 是个例外:它使用提供的 checkBotId 函数,而不是验证码令牌或 /siteverify 调用。
- 如果令牌缺失、被验证码提供者拒绝,或者
/siteverify端点不可用,插件会返回错误并中断请求。 - 如果令牌被验证码提供者接受,中间件会返回
undefined,表示允许请求继续处理。 - 对于 Vercel BotID,如果
checkBotId(或您的自定义validateRequest)判定请求来自机器人,则拒绝该请求;否则允许请求继续处理。
插件选项
provider(必需):验证码提供者。secretKey(除vercel-botid外所有提供者均必需):提供者的密钥,用于服务器端验证。endpoints(可选):选择需要 CAPTCHA 保护的路径。默认情况下,/sign-up/email、/sign-in/email和/request-password-reset受保护,其他路径不需要 CAPTCHA。设置此项后,它会替换默认值,因此应列出所有需要保护的路径。可使用精确路径或通配符,例如/sign-in/*匹配一个路径段,/sign-in/**匹配嵌套路由。minScore(可选,仅适用于 Google ReCAPTCHA v3):最低分数阈值,默认值为0.5。siteKey(可选,仅适用于 hCaptcha 和 CaptchaFox):防止在一个站点密钥上签发的令牌在其他站点上被兑换。siteVerifyURLOverride(可选,仅适用于基于令牌的提供者):覆盖 CAPTCHA 验证 URL。checkBotId(Vercel BotID 必需):Vercel 服务器端检查函数,从应用中的botid/server导入。如需传入 SDK 选项,请将其包装在函数中。validateRequest(可选,仅适用于 Vercel BotID):自定义验证逻辑。返回true以允许请求,返回false以拒绝请求。默认情况下,仅允许isBot: false的结果。