@dxv-systems/turnstile

中文文档
0.3.2发布于 2026/11/10MITTypeScriptCommonJS零依赖近 30 天下载 9807

Cloudflare Turnstile — 现场验证核心, Express and Next.js 路由守护, 以及反应部件

中文使用文档
文档目录11 节
  1. 入境点
  2. 服务器
  3. 否认的
  4. 客户端地址
  5. 决定 failClosed
  6. 核心 API
  7. 客户端
  8. 主题
  9. 测试地点密钥
  10. 把它包装在你的应用程序
  11. 模块格式

@dxv-系统/翻转

用于服务器和客户端的 Cloudflare Turnstile: /siteverify 核心,用于 Express 和 Next.js App 路由器的路由保护,以及一个反应部件.

npm i @dxv-systems/turnstile

入境点

导入目录
@dxv-systems/turnstile核心 : verifyTurnstileToken, (中文(简体) ), evaluateTurnstile, (中文(简体) ), clientIp, (中文(简体) ), turnstileHeaders, (中文(简体) ), TURNSTILE_HEADER, (中文(简体) ), TURNSTILE_TEST_SITE_KEY
@dxv-systems/turnstile/expressrequireTurnstile 中间软件
@dxv-systems/turnstile/nextassertTurnstile 用于获取风格的路由处理器
@dxv-systems/turnstile/reactTurnstile 部件组件,加 turnstileHeaders, (中文(简体) ), TURNSTILE_HEADER, (中文(简体) ), TURNSTILE_TEST_SITE_KEY

客户端发送符号在 X-Turnstile-Token 请求标题( e)TURNSTILE_HEADER) (中文(简体) ).

服务器

两名警卫都采取相同的两个选择,并共享一个政策执行,所以他们的行为都是一样的.

选项含义
secret例如, 您的曲折密钥 process.env.TURNSTILE_SECRET_KEY。 。 。 . undefined 是外部生产的有效状态.
failClosed真是个 没有秘密 意味着. true:以503来否认,而不是服务于无人看守的路线. false:没有秘密,没有警卫.

快递

import { requireTurnstile } from "@dxv-systems/turnstile/express";

app.post("/api/login", requireTurnstile({
  secret: process.env.TURNSTILE_SECRET_KEY,
  failClosed: isProduction(),
}), handler);

一个被拒绝的请求得到一个JSON的身体 { message } ,其状况见下表.

Next.js App路由器

import { assertTurnstile } from "@dxv-systems/turnstile/next";

export async function POST(req: NextRequest) {
  const denied = await assertTurnstile(req, {
    secret: process.env.TURNSTILE_SECRET_KEY,
    failClosed: isProduction(),
  });
  if (denied) return denied;

  const body = Body.parse(await req.json());
  // ...
}

assertTurnstile 使用纯网络 Request 返回平面 Response (或 null 请求何时通过)。 它不导入 Next, 所以它在任何抓取式处理器中有效 。 它从不读取尸体, 所以你的处理者仍然可以分析它.

否认的

每个案件都未能结案,只有一个故意例外.

情况结果
没有秘密, failClosed: false允许:明显的"这里没有警卫"状态
没有秘密, failClosed: true503和错误日志
请求时没有令牌403,不打电话 /siteverify
驳回质疑403, 登录错误代码
/siteverify 无法到达、 时间已过期或返回 5xx503:停电不能成为绕道
秘密错误( O)invalid-input-secret (以千美元计)503, 不是403: 这是服务器配置错误, 不是机器人

failClosed 管理一个 仅无秘密。一旦一个秘密被设定,一个缺失的代币和一个无法使用的支票都否认.

客户端地址

remoteip 从 x-real-ip 只请求标题, 永远不要 x-forwarded-for。来电者可以自己发送 x-forwarded-for,并代理它附着而不是替换它,所以其最左侧的条目是调用控制. 确定您的反向代理或主机集 x-real-ip 到客户端地址.

没有退路。 Cloudflare 得分符号对 remoteip因此,一个错误的数值比没有更糟糕。 当信头缺席时,没有 remoteip 发送.

决定 failClosed

这个包从不读取环境. 应用程序如何识别自己的生产部署 不同每个主机,所以你通过 failClosed 你自己来 典型的选择 : true 在每一个有真正部件和秘密的环境(生产、中转), false 在本地开发和丢弃预览环境中.

小心点 NODE_ENV: 许多设置 "production" 用于每个构件,包括预览,所以它往往本身不是一个可靠的信号.

核心 API

需要其它框架时直接使用核心 :

  • verifyTurnstileToken(token, secret, remoteIp?) 电话 /siteverify 并决心 { ok: true }, (中文(简体) ), { ok: false, reason: "rejected", codes } 或者说 { ok: false, reason: "unavailable", detail }从不扔出.
  • evaluateTurnstile({ secret, failClosed, token, remoteIp?, path? }) 执行上述政策并决心 { allow: true } 或者说 { allow: false, status: 403 | 503, message }。 。 。 . path 仅在日志行中使用.
  • clientIp(get) 读取 x-real-ip 通过一个标题获取器 (name) => string | null | undefined。 。 。 .

客户端

import { Turnstile, turnstileHeaders, type TurnstileHandle } from "@dxv-systems/turnstile/react";

const [token, setToken] = useState<string | null>(null);
const widget = useRef<TurnstileHandle>(null);

async function onSubmit() {
  try {
    await fetch("/api/login", {
      method: "POST",
      headers: { "Content-Type": "application/json", ...turnstileHeaders(token) },
      body: JSON.stringify({ email, password }),
    });
  } finally {
    widget.current?.reset(); // tokens are single-use
  }
}

<Turnstile ref={widget} siteKey={SITE_KEY} failedMessage="Verification could not load." onToken={setToken} />
<button type="submit" disabled={!token}>Sign in</button>

道具 : siteKey, (中文(简体) ), onToken, (中文(简体) ), failedMessage选择 className 财务报告和审定财务报表 theme。 。 。 . siteKey 财务报告和审定财务报表 failedMessage 是道具,不是从环境读取:每个捆绑者的公共可变前缀不同(VITE_*, (中文(简体) ), NEXT_PUBLIC_*),并非每个应用程序都有i18n运行时间.

主题

theme 默认为 "light"不是Cloudflare自己来的 "auto"。 。 。 . "auto" 遵循操作系统的 prefers-color-scheme而不是你的应用的主题。 仅限光的应用程序会向每个访问者显示一个黑暗部件,其OS处于黑暗模式.

过 "auto" 如果您的应用遵循系统方案,或 "dark" 如果它只是阴暗的。 带有自己的主题切换的应用程序应该通过当前主题, 所以部件在更改时会重新递归 .

测试地点密钥

如果没有真正的部件,例如在本地开发中或预览主机名中无法匹配部件域允许列表,请返回到 TURNSTILE_TEST_SITE_KEYCloudflare总是通过钥匙。 这不会削弱生产: 站点密钥是公用, 服务器是闸门, 用测试密钥刻出的一个符号失败 /siteverify 对一个真正的秘密.

把它包装在你的应用程序

旋转 ./react 而不是直接将其导入页面:

// components/turnstile.tsx
"use client"; // Next only

import { Turnstile as Base, TURNSTILE_TEST_SITE_KEY, type TurnstileHandle } from "@dxv-systems/turnstile/react";

export const Turnstile = forwardRef<TurnstileHandle, { onToken: (t: string | null) => void }>(
  function Turnstile(props, ref) {
    return (
      <Base
        ref={ref}
        siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY || TURNSTILE_TEST_SITE_KEY}
        failedMessage={t("turnstile.failed")}
        {...props}
      />
    );
  },
);

包装器提供站点钥匙和副本. 接下来也是 "use client" 边界。 包裹是自己的 "use client" 指令在建筑中幸存下来,但在建筑后着陆 "use strict" 因此,不要依赖它来为您设定边界.

模块格式

软件包是通用JS,所以在运行时间不能 require 仅依靠无害环境管理。 这个 ./react 条目不导入服务器代码, 因此 /siteverify 逻辑不包含浏览器捆绑.

版本与发布记录

@dxv-systems/turnstile 共发布 6 个版本,首次发布于 2026/08/19;过去 12 个月发布了 6 个版本。

版本发布日期距今
0.3.2latest2026/11/103 天前
0.3.12026/08/202 个月前
0.3.02026/08/202 个月前
0.2.02026/08/202 个月前
0.1.12026/08/192 个月前
0.1.02026/08/192 个月前

关于 @dxv-systems/turnstile 的常见问题

@dxv-systems/turnstile 是什么?

Cloudflare Turnstile — 现场验证核心, Express and Next.js 路由守护, 以及反应部件

如何安装 @dxv-systems/turnstile?

在项目目录运行 npm install @dxv-systems/turnstile,或使用 pnpm add / yarn add / bun add。

@dxv-systems/turnstile 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dxv-systems/turnstile 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@dxv-systems/turnstile 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@dxv-systems/turnstile 可以商用吗?

@dxv-systems/turnstile 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dxv-systems/turnstile 的下载量有多少?

根据 npm 官方下载统计,@dxv-systems/turnstile 在 2026/10/13 – 2026/11/11 这 30 天内被下载 9,807 次,日均约 327 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dxv-systems/turnstile 还在维护吗?

最新版本 0.3.2 发布于 2026/11/10(3 天前);至今共发布 6 个版本,其中过去 12 个月发布了 6 个;首次发布于 2026/08/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。