reCAPTCHA v3 令牌生成后仅两分钟有效,且只能验证一次。许多教程在页面加载时就请求令牌,导致用户填写较慢时提交已过期的令牌,出现验证失败。
修复方法是将 grecaptcha.execute() 移到表单提交处理程序中,在发送前才请求令牌,并在服务器端只验证一次。需要 PHP 开启 cURL 扩展,并从 reCAPTCHA 管理后台获取站点密钥和密钥。config.php 中建议将阈值设为 0.5,并从环境变量读取密钥,不要提交到 Git。
服务器端使用 cURL 调用 Google 验证接口,避免 allow_url_fopen 被禁用的问题,并能获得更清晰的错误信息。同一令牌不能重复验证,第二次调用会直接失败。表单按钮建议在提交时禁用,防止重复点击发送相同令牌。
如果使用 AJAX 或 fetch 提交,也应在请求发出前立即请求令牌,重试时重新请求。页面中有多个表单时,给每个表单分配独立的 action 名称,传入对应的验证函数,避免令牌被跨表单误用。
不要尝试延长令牌有效期,Google 不提供此设置。定时刷新令牌也不是推荐做法,后台标签页计时器可能被浏览器限制,旧标签页返回时仍可能提交过期令牌。以提交时生成令牌为主。
