Node.js+Express集成reCAPTCHA遇验证错误,请求排查问题
解决reCAPTCHA验证时的「缺少input response/secret」错误
我之前也踩过这个坑!核心问题是Google的reCAPTCHA验证接口不接受JSON格式的请求体,它要求参数以application/x-www-form-urlencoded(表单编码)的格式传递。你虽然能在日志里看到token,但用request-promise发送请求时的参数格式不对,导致Google识别不到你传的secret和response参数,才会返回这个错误。
常见错误代码示例
你大概率是这么写的(用JSON格式传参):
const rp = require('request-promise'); app.post('/submit-form', async (req, res) => { const recaptchaToken = req.body['g-recaptcha-response']; console.log('获取到的token:', recaptchaToken); try { const verifyResult = await rp({ method: 'POST', uri: 'https://www.google.com/recaptcha/api/siteverify', body: { secret: '你的服务器端密钥', response: recaptchaToken }, json: true // 这会让请求体以JSON格式发送 }); // 后续处理... } catch (err) { console.error(err); res.status(400).send('CAPTCHA验证失败'); } });
修正方法:改用表单编码格式传参
request-promise提供了form选项,会自动帮你把参数编码成表单格式,并设置正确的Content-Type请求头,这是最简单的修正方式:
const rp = require('request-promise'); app.post('/submit-form', async (req, res) => { const recaptchaToken = req.body['g-recaptcha-response']; console.log('获取到的token:', recaptchaToken); try { const verifyResult = await rp({ method: 'POST', uri: 'https://www.google.com/recaptcha/api/siteverify', form: { // 这里用form代替body secret: '你的服务器端密钥', response: recaptchaToken, remoteip: req.ip // 可选:加上用户IP,验证更准确(仅reCAPTCHA v2/v3支持) }, json: true // 这个可以保留,用来自动解析响应为JSON对象 }); if (verifyResult.success) { // CAPTCHA验证通过,处理表单提交逻辑 res.send('表单提交成功!'); } else { res.status(400).send('CAPTCHA验证失败,请重试'); } } catch (err) { console.error('调用reCAPTCHA接口出错:', err); res.status(500).send('服务器内部错误'); } });
额外检查点
- 确认你用的是服务器端密钥(不是客户端的Site Key),密钥可以在Google reCAPTCHA控制台里找到,别搞混了。
- 确保你的Express应用已经配置了
express.urlencoded()中间件,不然无法正确解析前端传来的表单数据(包括g-recaptcha-response):app.use(express.urlencoded({ extended: true })); - 如果是reCAPTCHA v3,还可以检查一下你的评分阈值设置,不过这和当前错误无关,只是后续可能会用到。
内容的提问来源于stack exchange,提问作者Willem van der Veen
相关产品推荐
相关产品推荐

