You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Google reCAPTCHA v2 siteverify API返回异常数据问题排查

关于Vue-Express应用中Google reCAPTCHA v2隐形模式的验证问题

我开发了一个带注册/登录页面的Vue-Express应用,在两个页面里都用了Google reCAPTCHA v2的隐形验证模式,手动调用execute函数拿到了如下有效token:

03AEkXODA0y6WEjvR8wd507P9Bnmm63hcOP2gMGJBsuN7PFpFJbeGE3r2M-3btinH4xMIu3OeFnpmLwrwJvlhPbyX7dkCzD_3jnbytUr7wrLC0X55O7qO3wrlF94H2ydekNYPutxvj-XaRKWcq_Dw96B5zSuc7h0xqqJgbao54jqHEB3RC5C0MWPkI6tf44TydsUscwlas9lKHG5tQZYNkOdtVwael4SUJuCvs6A5EADsKnUUKHOvfMX1a3-BUDC3fy1bRmqc7uGrmu-_6UUxNN10-7jR_9Cu9AZq94DGQ8YTnN0OJ0Jl_3w5ehl1HToAkW-RX4xWZsJlprccUm8P2Pk30W_KVGrm7W-N_z9w0c-MdFZfH7qV1xkf_hHO6hidvf_WYB_Sw8fBujV8PihixKSH6DKtsn3rVX4tA9BuyxVTTse4g1skqmpxF4Lp3CjAtzRJWwbtKLYCNHy0cTyIZ2AAR1v9QLMY4Mlz5DXIuFb4YTecvsjlxTG6F09gGjMWrWiQ4H-6q7BfE

之后把这个token传给Express后端,调用Google的验证API:

https://www.google.com/recaptcha/api/siteverify?secret=<recaptcha_secret_key>&response=<token>

此时后端得到异常响应(见截图),但用Postman发送完全相同的请求时,返回结果是:

{
    "success": false,
    "error-codes": [
        "timeout-or-duplicate"
    ]
}

我搞不清问题出在哪,求解决思路。


更新:获取token的代码逻辑

点击登录按钮时会调用onCaptchaVerified方法,同时该方法也会被验证码组件携带有效token再次触发,代码如下:

Vue组件中的验证码标签:

<vue-recaptcha
  ref="recaptcha"
  size="invisible"
  verify="onCaptchaVerified"
  expired="onCaptchaExpired"
  sitekey="sitekey"
/>

对应的方法实现:

async onCaptchaVerified(token) {
  await this.$refs.recaptcha.execute()
  
  if(!token) {
    return false
  }

  console.log("logging in...", token);

  const res = await postRequest('validate-human', {
    token: token
  })

  console.log(res.data.data)
}

问题分析与解决建议

  • 重复调用execute导致token失效
    隐形reCAPTCHA的verify回调本身就是验证成功后返回有效token的,你在回调里又调用了execute(),会再次触发验证生成新token,或者把当前token标记为已使用。当你用回调里的旧token去验证时,就会返回timeout-or-duplicate错误。
    解决:把execute()移到登录按钮的点击方法里,回调只处理token提交:

    // 登录按钮点击事件
    async handleLogin() {
      await this.$refs.recaptcha.execute()
    }
    
    // 验证成功回调
    async onCaptchaVerified(token) {
      if(!token) return false
    
      console.log("logging in...", token);
      const res = await postRequest('validate-human', { token })
      console.log(res.data.data)
    }
    
  • 组件绑定方式错误
    Vue中绑定事件应该用@前缀,你写的verify="onCaptchaVerified"会被当作字符串,可能导致回调触发异常。修正组件标签:

    <vue-recaptcha
      ref="recaptcha"
      size="invisible"
      @verify="onCaptchaVerified"
      @expired="onCaptchaExpired"
      :sitekey="sitekey"
    />
    
  • 后端请求方式问题
    Google推荐用POST请求调用siteverify API,GET方式可能因token过长导致URL截断,引发异常。后端改成POST请求:

    // Express后端示例
    const axios = require('axios');
    
    app.post('/validate-human', async (req, res) => {
      const { token } = req.body;
      const secretKey = '你的secret key';
    
      try {
        const response = await axios.post('https://www.google.com/recaptcha/api/siteverify', null, {
          params: {
            secret: secretKey,
            response: token,
            remoteip: req.ip // 可选,添加客户端IP提升验证准确性
          }
        });
        res.json(response.data);
      } catch (error) {
        res.status(500).json({ success: false, error: '验证请求失败' });
      }
    });
    
  • 防止重复提交
    检查是否存在按钮重复点击导致多次提交同一token的情况,添加按钮防抖或禁用逻辑,避免触发重复验证。

内容的提问来源于stack exchange,提问作者Rahul Mehta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:40:26