hankhu
带你看世界

Turnstile 验证码替代方案

本页内容来自官网,本人进行了取舍整理,并根据实践融合了部分自己看法,详细资料请查看官网内容

简介

Turnstile 是 Cloudflare 的智能验证码替代方案。它可以嵌入到任何网站中,无需通过 Cloudflare 发送流量,并且无需向访问者显示验证码即可工作。

Turnstile 目前处于公开测试阶段,可供所有客户免费使用
其以较小而简单的JavaScript 交互方式在其网站上的任何位置运行质询,包括工作量质询、空间质询、Web API 探测以及检测浏览器偏好和人类行为的各种其他验证。
因此,它根据特定请求微调验证难度,并避免向用户展示视觉验证的情况。避免验证码打开外部链接,这也减少了人类在互联网上解决验证码所花费的时间。
对于 Beta 版,每个站点每月对 siteverify 验证端点的调用仅限 100 万次。

形式

Turnstile小部件类型包括:

托管

Cloudflare 将使用来自访问者的信息决定是否应使用交互式质询。如果我们确实显示了交互,用户将被提示选中一个框(没有需要辨认的图像或文本)。

非交互式

一个完全非交互式的质询。浏览器质询运行时,用户会看到一个带有加载条的小组件。(转一圈,判断成功还是失败,失败了也不会让你选那个框而进行二次确认)

不可见

不需要交互的无可见质询(没有任何显示)


使用

要开始使用 Turnstile 小部件,您需要获取站点密钥和密钥。sitekey 和 Secret key 始终与一个小部件关联,不能重复用于其他小部件。
sitekey 是公开的,用于调用您站点上的 Turnstile 小部件。
sitekey 和密钥是在创建小部件时生成的,允许您的站点和 Cloudflare 之间进行通信,以验证来自 Turnstile 的已解决质询的响应。出于安全原因,请确保您妥善保管密钥。


总结:
sitekey 类似于公钥,可以理解为域名的编号,放在浏览器前端代码里,用于js发送api用
Secret key 相当于私钥,服务端验证用来验证前端质询是否成功。

注册

  1. 登录Cloudflare 仪表板,并选择您的帐户。
  2. 前往Turnstile。
  3. 在小部件概述中,选择“设置”
  4. 复制您的站点密钥和秘密密钥。

应用-渲染客户端集成

1.隐式渲染

1.1引入js

将 Turnstile 脚本片段插入 HTML<head>元素中:(其他地方也可)

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
1.2调用
<div class="cf-turnstile" data-sitekey="yourSitekey" data-callback="javascriptCallback"></div>

网页添加这行代码就行,js自动扫描 HTML 来查找具有cf-turnstile类名的元素,将此 div 标签 变为 验证的样式。
如果不要 调用js ,可以去掉 data-callback="javascriptCallback"
如果需要更改样式为白色的 可以添加 data-theme="light"

一旦解决了质询,就会将令牌传递给成功回调。该令牌必须根据我们的 siteverify 端点进行验证。一个token只能被验证一次。
令牌发出后,可以在接下来的 300 秒内进行验证。300 秒后,令牌不再有效,需要解决另一个质询。

示例-保护表格

Turnstile 通常用于保护网站上的表单,例如登录表单、联系表单等。
插入 JavaScript 脚本标签后,客户可以嵌入<div class="cf-turnstile"></div>到他们的网站中以保护他们的表单。

<form action="/login" method="POST">
<input type="text" placeholder="username"/>
<input type="password" placeholder="password"/>
<div class="cf-turnstile" data-sitekey="<YOUR_SITE_KEY>"></div>
<button type="submit" value="Submit">Log in</button>
</form>
//把代码里的<YOUR_SITE_KEY>改成网站的sitekey

此代码生成的样式是一个iframe,并且会添加一个带有不可见的元素,name为cf-turnstile-response,并将其与其他字段一起发送到服务器。

呈现小部件不会保护表单。作为渲染小部件结果的相应令牌也需要使用 siteverify API 进行验证。

假如设置了验证通过前提交按钮不可用,设置了回调 data-callback="javascriptCallback",验证成功后使按钮可用。

<script>
function javascriptCallback() {
            document.getElementById("submit").disabled = false;
}
</script>

查看官网的演示及其源代码

2.显式渲染

2.1引入js
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
2.1调用
创建一个div 名字为 example-container, 此名字可以自定义,但必须与js函数代码里选择查询的id 一致!
<script>
window.onloadTurnstileCallback = function () {
    turnstile.render('#example-container', {
        sitekey: '<YOUR_SITE_KEY>',
        callback: function(token) {
            console.log(`Challenge Success ${token}`);
        },
    });
};
<script>
//把代码里的<YOUR_SITE_KEY>改成网站的sitekey
//可以在callback里增加自己的代码,比如登陆按钮默认设置为disabled ,回调后 使 登陆 按钮可用

查看官网演示及其源代码

不建议使用不可见模式,会影响真正用户的通过率。
最好将属性配置ata-appearance="interaction-only",不需要质询时自动隐藏,需要质询时可自动出现。


配置

JavaScript 渲染参数数据属性描述
sitekeydata-sitekey每个小部件都有一个站点密钥。该站点密钥与相应的小部件配置相关联,并在创建小部件时创建。
actiondata-action客户值,可用于区分分析中同一站点密钥下的小部件,并在验证时返回。最多只能包含 32 个字母数字字符,包括_-
cDatadata-cdata客户有效负载,可用于在整个发布过程中将客户数据附加到挑战中,并在验证时返回。最多只能包含 255 个字母数字字符,包括_-
callbackdata-callback挑战成功后调用的 JavaScript 回调。回调会传递一个可以验证的令牌。
error-callbackdata-error-callback出现错误(例如网络错误或质询失败)时调用的 JavaScript 回调。请参阅客户端错误
executiondata-execution执行控制何时获取小部件的令牌,可以是 on render(默认)或 on execute。有关详细信息,请参阅执行模式。
expired-callbackdata-expired-callback当令牌过期并且不重置小部件时调用 JavaScript 回调。
before-interactive-callbackdata-before-interactive-callback在挑战进入交互模式之前调用的 JavaScript 回调。
after-interactive-callbackdata-after-interactive-callback当挑战离开交互模式时调用 JavaScript 回调。
unsupported-callbackdata-unsupported-callback当 Turnstile 不支持给定客户端/浏览器时调用 JavaScript 回调。
themedata-theme小部件主题。可以取以下值:lightdarkauto.

默认值为auto,尊重用户偏好。可以通过相应地设置主题来强制其变亮或变暗。
languagedata-language要显示的语言必须是:(auto默认)使用访问者选择的语言,或者 ISO 639-1 两个字母的语言代码(例如en)或语言和国家/地区代码(例如en-US)。有关详细信息,请参阅支持的语言列表。
tabindexdata-tabindexTurnstile 的 iframe 的 tabindex 用于辅助功能。默认值为0
timeout-callbackdata-timeout-callback挑战到期时调用的 JavaScript 回调。
response-fielddata-response-field控制是否创建带有响应令牌的输入元素的布尔值,默认为true
response-field-namedata-response-field-name输入元素的名称,默认为cf-turnstile-response.
size data-size小部件大小。可以取以下值:normalcompact.
retry data-retry控制小部件在未成功时是否应自动重试获取令牌。默认为auto,会自动重试。可以将其设置为never禁用失败时重试。
retry-interval data-retry-intervalretry设置为 时autoretry-interval控制重试尝试之间的时间(以毫秒为单位)。值必须是小于 的正整数900000,默认为8000
refresh-expired data-refresh-expired令牌过期时自动刷新。可以取automanual也可以never,默认为auto
appearancedata-appearance外观控制小部件何时可见。它可以是always(默认)、executeinteraction-only。有关详细信息,请参阅外观模式。

Token验证

客户必须调用 siteverify 端点来验证其网站后端的 Turnstile 小部件响应。小部件响应只有在经过 siteverify 端点验证后才被视为有效。仅响应的存在不足以验证它,因为它不能防止重放或伪造攻击。在某些情况下,Turnstile 可能会故意创建被 siteverify API 拒绝的无效响应。
使用成功回调通过显式或隐式渲染向 Turnstile 发出的令牌必须使用 siteverify 端点进行验证。
需要向 siteverify 端点传递与 sitekey 关联的密钥。当您创建小部件时,密钥将与站点密钥一起配置。
此外,响应需要传递到 siteverify 端点。
响应只能验证一次。如果相同的响应出现两次,则第二个和每个后续请求将生成一个错误,指出该响应已被消耗。

curl 'https://challenges.cloudflare.com/turnstile/v0/siteverify' --data 'secret=verysecret&response='
{
"success": true,
"error-codes": [],
"challenge_ts": "2022-10-06T00:07:23.274Z",
"hostname": "example.com"
}
//verysecret就是私钥
//请求方式支持GET或者POST都可以,返回json

js小dome

//官网的示例,
// This is the demo secret key. In production, we recommend
// you store your secret key(s) safely.
const SECRET_KEY = '1x0000000000000000000000000000000AA';

async function handlePost(request) {
	const body = await request.formData();
	// Turnstile injects a token in "cf-turnstile-response".
	const token = body.get('cf-turnstile-response');
	const ip = request.headers.get('CF-Connecting-IP');

	// Validate the token by calling the
	// "/siteverify" API endpoint.
	let formData = new FormData();
	formData.append('secret', SECRET_KEY);
	formData.append('response', token);
	formData.append('remoteip', ip);

	const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
	const result = await fetch(url, {
		body: formData,
		method: 'POST',
	});

	const outcome = await result.json();
	if (outcome.success) {
		// ...
	}
}

自用PHP验证token示例

 if (isset($_POST['submit']) && isset($_POST['cf-turnstile-response'])) {
    $ver_url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
    $secret = '1x0000000000000000000000000000000AA';
    $token = $_POST['cf-turnstile-response'];
    $ver_data = 'secret='.$secret.'&response='.$token;
    $ver_result =  curldata($ver_url,$ver_data);
    $result = json_decode($ver_result);
    if(!$result->success) {
        $error = "token错误";
        //echo $error;
    }
}
function curldata($url, $data) {
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_POST, 1);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
   curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
   curl_setopt($ch, CURLOPT_HEADER, 0);
   curl_setopt($ch, CURLOPT_TIMEOUT, 10);
   $output = curl_exec($ch);
   curl_close($ch);
   return $output;
}
 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

转载请注明出处:hankhu » Turnstile 验证码替代方案
分享到: 生成海报
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活