reCAPTCHA V3:闲置后如何处理过期的令牌?

时间:2019-01-30 09:56:17

标签: javascript token recaptcha recaptcha-v3

对于Google reCAPTCHA V2,很清楚令牌由于闲置而过期时该怎么办:客户可以进行更改,再次单击reCaptcha复选框。 对于Google reCAPTCHA V3,有所不同,因为尚不清楚令牌由于空闲而何时过期。

对于reCAPTCHA V3,Google建议:

https://developers.google.com/recaptcha/docs/v3

  1. 使用您的站点密钥加载JavaScript api

  2. 在操作或页面加载时上调用grecaptcha.execute //我们选择页面加载的时间,好吗?

  3. 将令牌发送到您的后端,并请求验证 //单击按钮后

好。如果在加载页面后几分钟点击了该按钮,则我们发送到后端的V3令牌已经过期。 在这种情况下应对的正确方法是什么?我们是否应该每分钟通过发送呼叫给Google来无声地自动更新令牌? 这种情况下最好的方法是什么?我没有找到Google的任何建议。

3 个答案:

答案 0 :(得分:2)

由于reCAPTCHA令牌在两分钟后过期,因此我将其工作:

第1步:在页面加载时加载验证码令牌(照常)

第2步:使用SetInterval函数每90秒重新加载令牌,以便刷新reCAPTCHA令牌,直到2分钟后过期。

//Onload
grecaptcha.ready(function () {
   grecaptcha.execute("YOUR_KEY_HERE", {action: "request_call_back"}).then(function (e) {
      $("#YOUR_FIELD_NAME_ID").val(e);
   });
});

//Every 90 Seconds
setInterval(function () {
   grecaptcha.ready(function () {
      grecaptcha.execute("YOUR_KEY_HERE", {action: "request_call_back"}).then(function (e) {
         $("#YOUR_FIELD_NAME_ID").val(e);
      });
}, 90 * 1000);

答案 1 :(得分:0)

令牌生成的时间必须晚于页面加载的时间。它应该在将其发送到后端之前立即生成。换句话说,我们单击按钮(在我的示例中),然后获取生成的令牌,然后将该令牌发送到后端。

此解决方案很有意义,并且可以解决我的问题。

答案 2 :(得分:0)

我以asp.net形式工作,但是该解决方案可以以任何语言应用。令牌过期的问题很烦人。

令牌在v3中的有效时间为2分钟,但是Google不建议您让计时器每2分钟刷新一次令牌的做法。他们建议仅在需要时刷新令牌。

我选择了一种javascript解决方案,迫使客户端单击刷新令牌的按钮。

应该注意,如果在刷新Recaptcha时执行“ recaptcha.ready”,则会引发错误,因此我必须将“ ready”与“ execute”分开,并以此刷新Recaptcha,而不会出现错误。

<script type="text/javascript" >
    grecaptcha.ready(function () {
      captcha_execute();
    });

    function captcha_execute() {
      grecaptcha.execute('<%=System.Configuration.ConfigurationManager.AppSettings("recaptcha-public-key").ToString %>', { action: 'ingreso_usuario_ext' }).then(function (token) {
        document.getElementById("g-recaptcha-response").value = token;
      });
    }

    function los_dos(token_viejo) {
      captcha_execute()
      clase_boton(token_viejo);
    }

    async function clase_boton(token_viejo) {
      btn_act = document.getElementById("Btn_Refrescar");
      btn = document.getElementById("Btn_Ingresar");
      btn.setAttribute("class", "button_gris");
      btn_act.style.display = "none";
      btn.style.display = "initial";
      btn.disabled = true;

      //token_viejo = document.getElementById("g-recaptcha-response").value;
      strToken = token_viejo;
      varCant = 0;

      while (strToken == token_viejo && varCant < 30) {
        strToken = document.getElementById("g-recaptcha-response").value;
        await sleep(100);
        varCant++;
      }

      btn.setAttribute("class", "button_azul");
      btn.disabled = false;

      setTimeout(refrescar_token, 120000);
    }

    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }

    function refrescar_token() {
      btn_ing = document.getElementById("Btn_Ingresar");
      btn_act = document.getElementById("Btn_Refrescar");
      btn_act.style.display = "initial";
      btn_ing.style.display = "none";
    }
  </script>

体内

<body style="background-color: #dededc;" onload="clase_boton('');" >

按钮

 <asp:Button ID="Btn_Ingresar" runat="server" Text="Ingresar" CssClass="button_gris" Enabled="false" />
 <input type="button" id="Btn_Refrescar" name="Btn_Refrescar" class="button_verde" value="Refrescar Token" title="Refrescar Token" onclick="los_dos(document.getElementById('g-recaptcha-response').value);" style="display: none;" />
          

使用javascript,我等待令牌被填充,并且在填充令牌时,启用登录按钮。如果该过程花费的时间太长(由于某些错误),我仍然会启用它。这是一个选择问题。

2分钟(“ setTimeout”)后,登录按钮不可见,我显示该按钮以刷新令牌。

我希望这可以帮助/指导您解决问题。