验证码

验证码插件

验证码插件通过在关键端点添加验证码验证,为您的 Better Auth 系统集成了机器人防护功能。此插件确保只有人类用户可以执行注册、登录或重置密码等操作。当前支持的提供者有:

默认端点涵盖邮箱和密码身份验证。其他身份验证方法需要显式配置端点数组。Vercel BotID 还需要按照下方说明进行客户端设置。

安装

安装依赖(可选)

如果您使用 Vercel BotID,请在应用中安装其 SDK:

npm install botid

将插件添加到 auth 配置中

auth.ts
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, 
        }, 
    }, 
});

提供者

Vercel BotID

BotID 需要 Vercel 部署和客户端设置。请按照 Vercel 的设置指南,根据您的框架配置重写规则并集成客户端。Better Auth 插件不使用 secretKey 或 x-captcha-response 头:

auth.ts
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 的结果。