表单人机验证选择,reCAPTCHA与hCaptcha对比
表单被机器人刷提交,最省事的办法就是加一道人机验证。reCAPTCHA 和 hCaptcha 是目前最常用的两个第三方方案,但它们的可用性、隐私策略和接入成本差别不小。下面从选型判断讲到具体接入,零基础也能照着做。
## 先判断你的站点适合哪一个
选型的关键不是哪个技术更强,而是你的访客从哪里来、站点是否面向国内用户。
- **访客主要在国内、且没有稳定代理出口**:优先考虑 hCaptcha。reCAPTCHA 依赖 Google 域名,国内网络下脚本加载和验证接口经常超时,用户会卡在“验证中”。
- **访客以海外为主、已有 Google 生态**:reCAPTCHA v3 可以无感打分,体验更顺,适合登录、注册、评论等高频场景。
- **对隐私合规敏感、不想把用户行为数据交给 Google**:hCaptcha 在隐私说明上更明确,且支持自建企业版。
一句话结论:**面向国内用户的表单,默认先测试 hCaptcha 的连通性;面向海外用户再评估 reCAPTCHA。**
## 接入前需要准备什么
两个平台都需要先注册账号并创建站点,拿到一对密钥:
- **Site Key(站点密钥)**:放在前端页面,公开可见,用于渲染验证组件。
- **Secret Key(密钥)**:只放后端,用于向平台接口校验用户提交的 token,绝对不能写进前端 JS。
操作路径大致如下:
1. 打开对应平台官网,注册账号。
2. 进入控制台的 Sites / 站点管理,点击新建站点。
3. 填写域名,注意不要带 `https://` 和路径,例如 `example.com`。
4. 提交后复制 Site Key 和 Secret Key,Secret Key 只显示一次,建议先存进密码管理器或环境变量。
## 前端渲染:两种组件的写法差异
reCAPTCHA v2 会在页面插入一个复选框,用户点击后完成验证;hCaptcha 的交互几乎一样,替换脚本和 class 即可。
reCAPTCHA 前端示例:
```html
```
hCaptcha 前端示例:
```html
```
两个组件都会在表单里生成一个隐藏字段(通常名为 `g-recaptcha-response` 或 `h-captcha-response`),后端要读取的就是这个 token。
**验证方法**:页面加载后组件能正常显示、点击后出现绿色对勾,说明 Site Key 和域名配置正确。如果显示“invalid domain”,回到控制台检查域名是否填错。
## 后端校验:必须做的一步
前端通过只代表用户完成了验证,真正决定放不放行的是后端。以 PHP 为例,核心逻辑是拿 token 去平台接口换结果:
```php
$token = $_POST['h-captcha-response'] ?? '';
$secret = getenv('HCAPTCHA_SECRET');
$resp = file_get_contents(
"https://hcaptcha.com/siteverify?secret={$secret}&response={$token}"
);
$data = json_decode($resp, true);
if (empty($data['success'])) {
exit('验证失败,请重试');
}
```
reCAPTCHA 的校验地址是 `https://www.google.com/recaptcha/api/siteverify`,参数名同样是 `secret` 和 `response`,返回结构也类似。
**注意**:token 是一次性的,且有效期很短,校验失败后要让用户重新验证,不要缓存复用。
## 常见报错与避坑清单
- **组件一直转圈或显示“无法加载”**:多半是脚本域名被墙或 DNS 污染。国内服务器上直接访问 `https://www.google.com/recaptcha/api.js` 测试,超时就说明 reCAPTCHA 不可用。
- **后端校验始终返回 false**:先确认 Secret Key 没有多余空格,再确认 token 字段名拼写正确。hCaptcha 的字段是 `h-captcha-response`,不是 `g-recaptcha-response`。
- **本地开发正常、上线就失败**:检查生产域名是否已在控制台登记,子域名要单独添加。
- **把 Secret Key 写进前端**:这是最常见的严重错误,等于把校验能力公开,别人可以伪造通过。
## 怎么确认防刷真的生效
接入完成后不要只看页面能显示。用命令行模拟一次提交,观察后端是否拒绝空 token:
```bash
curl -X POST https://你的域名/表单接口 \
-d "name=test&h-captcha-response=invalid"
```
预期结果是返回“验证失败”,而不是成功写入数据库。再手动提交一次正常表单,确认能通过并收到数据。两步都符合,才说明前后端校验链路是通的。
如果站点访问量不大,也可以先用平台免费额度观察一段时间,再决定是否升级到企业版。具体额度和价格会调整,建议以官方控制台实际显示为准。
**最后提醒**:人机验证只是第一道门槛,表单接口仍要做频率限制、字段长度校验和敏感词过滤,单靠验证码挡不住所有自动化攻击。