【问题标题】:invalid-input-secret for google's recaptcha api谷歌recaptcha api的无效输入秘密
【发布时间】:2015-08-23 11:14:07
【问题描述】:

我正在尝试在我的网站上使用 recaptcha。带有 express 框架的 Nodejs 服务器。该网站没有被托管,我仍在本地处理它。在主页上,用户输入他的信息创建帐户,并解决了recaptcha,我发送结果

$("#g-recaptcha-response").val()

到服务器。在我的服务器上,

https.get("https://www.google.com/recaptcha/api/siteverify?secret=" + SECRET + "&response=" + key, function(res) {
            var data = "";
            res.on('data', function (chunk) {
                    data += chunk.toString();
            });
            res.on('end', function() {
                    try {
                            var parsedData = JSON.parse(data);
                            console.log(parsedData);
                            callback(parsedData.success);
                    } catch (e) {
                            callback(false);
                    }
            });
    });

其中 key 是响应,SECRET 是他们给你的密钥。我宣布 一个变量 SECRET 并将密钥作为字符串存储在其中。

每一次,都是为了

console.log(parsedData); 

这是说

{ success: false, 'error-codes': [ 'invalid-input-secret' ] }

我复制粘贴了秘钥,怎么会失效呢。只有在“秘密参数无效或格式错误”时才应该显示此错误,正如其website 上所说的那样。我关注了这个tutorial

【问题讨论】:

  • 密钥是否包含任何“特殊”字符,这些字符可能在 URL 中具有定义的含义? (例如问号或 & 号,或非 ASCII 字符)也许您只需要正确地对值进行 URL 编码?
  • @CBroe 秘密包含一些下划线 _,我将如何对值进行 URL 编码?
  • 不,那些应该没问题。但是查看您链接到的文档,它说它需要是 POST 请求,而您现在正在执行 GET。
  • 我只是复制并粘贴了我在该网站上看到的内容(教程),他使用了一个 get。我尝试更换它,但出现了一些错误。我是否需要立即托管我的网站才能使其正常工作,因为我不需要,我只是在本地服务器上完成所有这些工作。
  • 更新的解决方案已经发布在这里:stackoverflow.com/a/66900684/11636916

标签: node.js post get recaptcha


【解决方案1】:

我也按照教程进行操作,然后遇到了您在此处报告的相同错误。仔细查看tutorial 中的屏幕截图,它显示

使用这些参数发送 GET 请求

并检查 Google reCaptcha website 它说

使用这些参数发送 POST 请求

我很好奇谷歌是否改变了他们对 POST 而不是 GET 的想法,或者教程中的屏幕截图来自不同的来源。

无论如何,我已经调整了教程中的代码版本以发出 POST 请求(下面的代码使用 querystring 模块),见下文:

var SECRET = "YourSecretHere";

// Helper function to make API call to recatpcha and check response
function verifyRecaptcha(key, callback) {
  //declare above var querystring = require('querystring') on top
  var post_data = querystring.stringify({
    'secret' : SECRET,
    'response': key
  });

  var post_options = {
    host: 'www.google.com',
    port: '443',
    method: 'POST',
    path: '/recaptcha/api/siteverify',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': Buffer.byteLength(post_data)
    }
  };
  var req = https.request(post_options, function(res) {
    var data = "";
    res.on('data', function (chunk) {
      data += chunk.toString();
    });
    res.on('end', function() {
      try {
        var parsedData = JSON.parse(data);
        callback(parsedData.success);
      } catch (e) {
        callback(false);
      }
    });
  });
  req.write(post_data); 
  req.end();
  req.on('error',function(err) {
    console.error(err);
  });
}

我还想补充一点,remoteip 字段是可选的,但是,如果您愿意,也可以传递该值。为此,您需要从连接对象中检索 remoteIpAddress,或者只需在您的应用上启用 trust proxy,如下所示:

app.enable('trust proxy'); 

然后将 ip 地址传递给 verifyRecaptcha,调用如下所示:

verifyRecaptcha(req.ip, req.body["g-recaptcha-response"], function(success) {
   if(success) { ...} else { ... } 
}); 

然后您需要修改 post_params 以包含 remoteip 字段,如下所示:

var post_data = querystring.stringify({
    'secret' : SECRET,
    'response': key,
    'remoteip': ip
  });

app.enable('trust proxy'); 允许 req.ipreq.ips 这是一个 IP 地址数组。有关获取请求 IP 地址的更多信息,请参阅此 SO question

如果您正在开发并且厌倦了所有棘手的著名和最烦人的Street Names reCaptcha,那么我建议您使用谷歌提供的测试SiteSecret keys 来覆盖验证码解决以加快速度向上发展。见here

【讨论】:

  • 我登录只是为了支持你的回答,很好!虽然之后我遇到了和 Rockstar5645 说的一样的问题,但我不得不直接添加变量 SECRET。此外,您在第 4 行“rqeuire”中有一个小错字:P
  • @LightFlow 很高兴这个答案很有帮助。顺便说一句,我更新了答案以显示添加 remoteip 这是可选的。我还提供了有关使用默认开发站点和密钥来加速开发的说明(跳过 reCaptcha 解决)。解决路牌 reCaptcha 非常烦人:(
【解决方案2】:

这真的很愚蠢,我不敢相信我在上面浪费了这么多时间,但我没有使用变量 SECRET,而是将我的密钥添加到 url 并且它起作用了。

【讨论】:

  • 我尝试直接添加 SECRET,但对我不起作用 :( 然后我尝试将 GET 转换为 POST 请求并设法让它工作。发布我的解决方案,以防万一对有相同问题的其他人有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-06
  • 2019-01-18
  • 2021-09-25
  • 2015-12-02
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
相关资源
最近更新 更多