域名 AXUM.RS 将于 2025 年 10 月到期。我们无意再对其进行续费,如果你有意接续这个域名,请与我们取得联系。
  • AXUM.RS 现仅需人民币 3000 元(大写:叁仟元整。接受适度议价
  • 按照行业规则,AXUM.RS 到期后,大概率会进入长时间的赎回期,该期间内,如果你想拥有该域名,将要付出高额的费用
  • 我们已启用 AXUM.EU.ORG 域名,并将持续运营
  • 仅接受微信或支付宝交易
如果你对 AXUM.RS 有兴趣,请和我们进行联系:

注册 Cloudflare Turnstile 并将其集成到 AXUM 应用中

本章将讨论注册 Cloudflare Turnstile 并将其集成到 AXUM 应用中。

和 Google reCaptcha 以及 hCaptcha 类似,Cloudflare Turnstile 也是用于人机验证的,和前两者不同的是,Turnstile 不再要求用户完成各种奇奇怪怪的挑战,而是利用自身的算法,「无感」的进行人机验证,用户体验提升非常大。

注册 Turnstile

登录到 Cloudflare 用户面板,依次点击:Turnstile - Add widget,如下图:

turnstile-1

输入名字,然后依次进行如下操作:点击 Add Hostnames - 选择要添加的域名 - 点击 Add 按钮。如下图:

turnstile-2-1

之后,点击页面右下角的 Create 按钮:

turnstile-2-2

然后你将看到成功页面。该页面显示了 Site Key 和 Secret Key。需要把它们复制保存起来,后面将会用到。

turnstile-3

Turnstile 的两个 Key

注册之后,我们会得到两个 Key,它们的作用分别是:

  • Site Key:用于客户端,在显示人机验证小部件时使用
  • Secret Key:用于服务端,在进行人机验证合法性校验时使用

注册时生成的两个 Key 不能直接用于本地开发,因为它们和域名绑定。除非你使用某些技术,将本地开发环境绑定到注册 Turnstile 时添加的域名。相比来说,使用 Turnstile 提供的测试 Key 会简单很多。以下是 Turnstile 的测试 Key:

  • Site Key:1x00000000000000000000AA
  • Secret Key:1x0000000000000000000000000000000AA

将 Turnstile 集成到 AXUM 应用中

我们需要对用户提交的人机验证进行校验,在之前的《axum 集成hcaptcha验证码进行人机验证》一文中,我们介绍了如何集成 hCaptcha 人机验证,幸运的是,集成 Turnstile 和它几乎一模一样:

use serde::Deserialize;

use crate::{config, Error, Result};

#[derive(Deserialize)]
pub struct Response {
    pub success: bool,
}

pub async fn verify(cfg: &config::Turnstile, token: &str) -> Result<Response> {
    let form = [("secret", cfg.secret_key.as_str()), ("response", token)];
    let client = reqwest::ClientBuilder::new()
        .timeout(std::time::Duration::from_secs(cfg.timeout as u64))
        .build()
        .map_err(Error::from)?;
    let res = client.post(&cfg.validation_url).form(&form).send().await?;
    let res = res.json().await?;
    Ok(res)
}
#[derive(Deserialize)]
pub struct Response {
    pub success: bool,
}

用于封装 Turnstile 服务器返回给我们的响应。它的响应数据远不止一个字段,但对于我们而言,有一个标识是否成功的 success 字段就足够了。详细信息,你可以查看官方文档

向 Turnstile 服务器请求验证

pub async fn verify(cfg: &config::Turnstile, token: &str) -> Result<Response> {
    let form = [("secret", cfg.secret_key.as_str()), ("response", token)];
    let client = reqwest::ClientBuilder::new()
        .timeout(std::time::Duration::from_secs(cfg.timeout as u64))
        .build()
        .map_err(Error::from)?;
    let res = client.post(&cfg.validation_url).form(&form).send().await?;
    let res = res.json().await?;
    Ok(res)
}
  • 验证数据:Turnstile 服务器验证需要两个数据:

    • secret:就是我们注册时生成给我们的 Secret Key。如果用于本地开发,可以使用 1x0000000000000000000000000000000AA
    • response:用户完成人机验证后,Turnstile 生成的响应令牌。它由客户端传入。
  • Turnstile 配置。我们使用了项目中的 Turnstile 配置,它的定义如下:

    #[derive(Deserialize, Serialize)]
    pub struct Turnstile {
        /// 安全密钥
        pub secret_key: String,
        /// 验证地址
        pub validation_url: String,
        /// 超时秒数
        pub timeout: u8,
    }
    

将 Turnstile 集成到项目前端

由于我们前端使用 React 构建,已经有封装好的组件供我们直接使用了。如果你想了解最原始的集成方式,可以查看官方文档

本章代码位于04.注册Turnstile并集成到AXUM中分支。

要查看完整内容,请先登录