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

axum 集成hcaptcha验证码进行人机验证

为什么使用 hCaptcha?

  • Google 的 reCaptche 在国内无法访问,但 hCaptcha 可以

  • 在开发层面 hCaptcha 兼容 reCaptche

  • hCaptcha 会给站长提供一定的收益

Google 的 reCaptche 在国内无法访问,但 hCaptcha 可以

在开发层面 hCaptcha 兼容 reCaptche

hCaptcha 会给站长提供一定的收益

开始之前,你需要注册一个 hCaptcha 账户,并添加站点。之后,你会得到一个Site Key,它用于在网页上显示人机验证。除此之外,你还需要在这里 拿到 Secret Key,它用于将用户的人机验证结果提交到服务器上进行验证。

你需要进行以下操作,以便在页面中显示 hCaptcha:

  • 引入官方的 JS 文件:<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

  • 在需要显示人机验证的地方:<div class="h-captcha" data-sitekey="{{ site_key }}"></div>

引入官方的 JS 文件:<script src="https://js.hcaptcha.com/1/api.js" async defer></script>

在需要显示人机验证的地方:<div class="h-captcha" data-sitekey="{{ site_key }}"></div>

hCaptcha 会把用户的人机验证结果保存到名为 h-captcha-response<textarea> 中,为了提交到 rust ,我们需要在用户提交表单前,将这个结果复制到我们自定义的隐藏域中,因为 h-captcha-response 并不符合。

你也可以在结构体中,利用 seder 来指定结构体字段反序列化的名字

你也可以在结构体中,利用 seder 来指定结构体字段反序列化的名字

验证用户提交的人机验证

我们需要对用户提交的人机验证结果发送到 hCaptcha 服务器进行有效性和正确性的验证:

/// 验证HCaptcha子模块
mod hcaptcha_verify {
    use serde::{Deserialize, Serialize};

    /// 提交验证的请求
    #[derive(Serialize)]
    pub struct VerifyRequest {
        pub secret: String,
        pub response: String,
    }

    /// 验证结果的响应
    #[derive(Deserialize)]
    pub struct VerifyResponse {
        pub success: bool,
    }

    /// 将用户的人机验证操作结果提交到服务器验证
    pub async fn verify(response: String, secret: String) -> Result<bool, String> {
        let req = VerifyRequest { secret, response };
        let client = reqwest::Client::new();
        let res = client
            .post("https://hcaptcha.com/siteverify")
            .form(&req)
            .send()
            .await
            .map_err(|err| err.to_string())?;
        let res = res.text().await.map_err(|err| err.to_string())?;
        let res: VerifyResponse = serde_json::from_str(&res).map_err(|err| err.to_string())?;
        Ok(res.success)
    }
}

只有通过了服务器验证的,才是真正有效的,才可以继续进行后续操作:

/// 反馈信息表单
#[derive(Deserialize)]
pub struct SubmitFeed {
    pub nickname: String,
    pub email: String,
    pub message: String,
    pub hcaptcha_response: String,
}

/// 反馈信息处理
async fn feed_action(
    Extension(cfg): Extension<HCaptchaConfig>,
    Form(frm): Form<SubmitFeed>,
) -> Result<Html<String>, String> {
    // 人机验证
    let result = hcaptcha_verify::verify(frm.hcaptcha_response, cfg.secret).await?;
    if !result {
        return Err("Please verify your hcaptcha".to_string());
    };

    let tpl = FeedActionTemplate {
        feed: Feed {
            nickname: frm.nickname,
            email: frm.email,
            message: frm.message,
        },
    };
    let html = tpl.render().map_err(|err| err.to_string())?;
    Ok(Html(html))
}

本章讨论了如何在 axum 中集成 hCaptcha 这个人机验证功能,完整代码可以在代码库找到。

  1. 请使用serde的命名功能,来指定结构体SubmitFeedhcaptcha_response 字段反序列化的名字为h-captcha-response

  2. 注册一个 hCaptcha 账号,并认识阅读其文档

注册一个 hCaptcha 账号,并认识阅读其文档

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