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

React使用Recaptcha3验证表单对接Firebase Functions出现token未定义及超时问题

问题原因与修复方案

一、初始token为undefined的问题

  • 取值对象错误:请求参数存放在req(请求对象)而非res(响应对象)上,你写的res.query.body完全错误
  • 字段名不匹配:前端通过GET查询参数传递的是token字段,不是body字段,正确写法是const token = req.query.token
  • 拼写错误:配置读取语句functions.config().recaptacha.key中多了一个字母a,若你的Firebase配置命名为recaptcha,此处需修正为functions.config().recaptcha.key

二、后续函数超时的问题

核心原因是HTTP类型的Firebase云函数必须主动返回响应给客户端,否则函数会一直挂起直到达到默认60秒的超时阈值。你当前的代码无论验证成功还是失败,都没有返回任何响应给前端,必然触发超时。同时catch块直接抛出错误不会被前端接收,需要通过响应对象手动返回错误信息。

修正后的云函数代码

const axios = require('axios')
const USER_ERROR_CODES = ['missing-input-response', 'invalid-input-response']

exports.sendRecaptcha = functions.https.onRequest(async (req, res) => {
    res.set('Access-Control-Allow-Origin', '*')
    res.set('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS')
    res.set('Access-Control-Allow-Headers', '*')

    // 处理跨域预检请求
    if (req.method === 'OPTIONS') {
      return res.status(204).send('')
    }

    try {
        const secret = functions.config().recaptcha.key;
        functions.logger.log("SECRET:", secret);

        const token = req.query.token;
        functions.logger.log("token", token);

        // 提前校验token是否存在
        if (!token) {
          return res.status(400).json({success: false, error: 'missing token'})
        }

        let result = await axios({
            method: 'post',
            url: 'https://www.google.com/recaptcha/api/siteverify',
            params: {
                secret: secret,
                response: token,
            }
        });
        let data = result.data || {};
        if(!data.success){
            return res.status(400).json({
                success: false,
                error: 'response not valid'
            })
        }
        // 验证成功返回结果给前端
        return res.status(200).json({success: true, score: data.score})
    } catch(err){
        console.log(err);
        const errorRes = err.response ? err.response.data : {success: false, error: 'captcha_error'}
        return res.status(500).json(errorRes)
    }
})

可选优化建议

  • 把前端GET请求改为POST请求传递token,GET参数会留存到请求日志中,安全性更低
  • 生产环境将跨域允许源*替换为你自己的前端域名,降低安全风险
  • 验证通过后增加score阈值判断,reCAPTCHA v3得分低于0.5可直接判定为机器操作,拒绝表单提交

内容的提问来源于stack exchange,提问作者Trond Kristiansen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:39:03