域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。
  • 方案1️⃣AXUM.RS 域名 = 3000
  • 方案2️⃣方案1️⃣ + 本站所有专题原始 Markdown 文档 = 5000
  • 方案3️⃣方案2️⃣ + 本站原始数据库 = 5500
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名(方案1️⃣),或者该域名到期,本站将启用新的免费域名继续提供服务。
  2. 如果有人购买了 AXUM.RS 域名,且同时购买了内容和/或数据库(方案2️⃣/方案3️⃣),本站将关闭。届时我们或许会以另一种方式与你再相遇。

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

在机器人采集、恶意攻击的今天,人机验证筑起了一道保护网。从之前的图片验证码,到 Google 提供的 reCaptcha,人机验证经历了一段漫长的演进过程。

为什么使用 hCaptcha?

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

  • 在开发层面 hCaptcha 兼容 reCaptche

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

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

在开发层面 hCaptcha 兼容 reCaptche

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

在页面中显示 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>

{%extends "base.html"%} {%block title%}反馈{%endblock%} {%block content%}
<form action="/feed" method="post" id="frmFeed">
  <input type="hidden" name="hcaptcha_response" id="hcaptcha_response" />
  <div class="mb-3">
    <label for="nickname" class="form-label">昵称:</label>
    <input
      type="text"
      class="form-control"
      name="nickname"
      placeholder="你的昵称"
      required
    />
  </div>
  <div class="mb-3">
    <label for="email" class="form-label">邮箱:</label>
    <input
      type="email"
      class="form-control"
      name="email"
      placeholder="你的邮箱"
      required
    />
  </div>
  <div class="mb-3">
    <label for="message" class="form-label">信息:</label>
    <textarea class="form-control" name="message" rows="3" required></textarea>
  </div>
  <div class="mb-3">
    <div class="h-captcha" data-sitekey="{{ site_key }}"></div>
  </div>
  <button type="submit" class="btn btn-primary mb-3">提交</button>
</form>
{%endblock%} {%block js%}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
<script>
  $(function () {
    $("#frmFeed").submit(function () {
      let res = $("[name=h-captcha-response]").val();
      if (!res) {
        alert("请进行人机验证");
        return false;
      }
      $("#hcaptcha_response").val(res);
    });
  });
</script>
{%endblock%}

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

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

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

验证用户提交的人机验证

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

/// 反馈信息表单
#[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 账号,并认识阅读其文档

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

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

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