Recaptcha3 、Javascript 和 Firebase 后端问题

Recaptcha3 , Javascript, and Firebase backend problem

我对 Javascript 比较陌生,所以请多多包涵。我已经用谷歌搜索和测试了一天但没有成功,所以我需要向社区寻求帮助。我正在尝试使用 Recaptcha3 验证我的 React JS 网站上联系表单的内容。我收到了基于表单内容(电子邮件、姓名)的令牌,看似正确,但将令牌发送到我的后端(Firebase 函数)不起作用。我不断崩溃:

....
2021-08-25T03:45:00.892Z I sendRecaptcha: token undefined
2021-08-25T03:45:01.198Z ? sendRecaptcha: { success: false, error: 'response not valid' }
2021-08-25T03:45:01.199Z ? sendRecaptcha: Unhandled rejection
2021-08-25T03:45:01.246Z ? sendRecaptcha: { success: false, error: 'captcha_error' }
2021-08-25T03:45:01.252056348Z D sendRecaptcha: Function execution took 374 ms, finished with status: 'crash'

我在表单上按下提交后的代码触发了一个云函数sendRecaptcha:

const handleSubmit = event => {
        event.preventDefault()

        const apiString = 'https://xxxx.cloudfunctions.net/sendRecaptcha'
        setLoading(true);
        window.grecaptcha.ready(() => {
            window.grecaptcha.execute(SITE_KEY, {action: 'form'})
                .then(function(token) {
                    console.log("TOKEN: ",token);

                    Axios.get(`${apiString}?token=${token}`)
                        .then(function (response) {
                            const score = response.data.score;
                            console.log("score: ", score);
                            sendVerifiedContent()

                            $("#contact").unbind('submit').submit();
                        })
                        .catch(function (error) {
                            console.log("error: ", error);
                        });
                });
        });
    }

我的 index.js 云函数(Firebase 函数):

const USER_ERROR_CODES = ['missing-input-response', 'invalid-input-response']

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

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

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

    try {
        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){
            throw({
                success: false,
                error: 'response not valid'
            })
        }
    }catch(err){
        console.log(err);
        throw err.response ? err.response.data : {success: false, error: 'captcha_error'}
    }
})

window.grecaptcha.execute 函数完成时,我看到了令牌,它看起来像这样(看起来不错):

03AGdBq255ghLC0DOUleaz71srZlcYWCiVlR-aldGXQZ6L2D-wIkJb5V_NDh66AYWsERT0w9hFLIt5nVikfjigufJvA2phS_ns-6X8YAza0S-nCS0RUPx1IgJBQUZ1Vl-Cc5AfuOcavSzCicNtSHAcLLXZPY-dY3PbIo-jzelpBelyfD8RGB8dKrWreP2cCfgitjs24xtX8J94ED3WC4DzQKCbfvEEQrEoAHWY2rueU2lDfflBybpz5u7lXccd_zDTORy9WEiHQBK2vEuEuJXZ-85mLP1acI03I1lOXpm_uLBTO3YJMpXc5Jq-4eRO4vDvox23YxfKYgXQd5UZPvkWQWq7sv_9ANUZK1w28LeK7aZO-9KUmGMmm3IFfaOKYrggVAIoEq8ex3unGZTxwq4ZnrYzYhGAx02PAmC5UQEjbBHLDStfYaaLHh8

但是一旦我的云函数被调用,我就无法从 req.query.token 获取令牌(functions.logger.log("token", token) 的输出未定义)并且函数的其余部分崩溃。

我确定这是一个初学者问题,但希望得到一些帮助。

更新 我遵循了@Dharmaraj 的建议,并且能够在我的云函数中正确获取令牌。该功能似乎卡住并超时。我的代码是否还有其他需要改进的地方?

D sendRecaptcha: Function execution took 60011 ms, finished with status: 'timeout'

query property exists on request object and not response。要访问查询参数,请将您的代码重构为:

const token = req.query.token;
// alternatively using object destructuring
const {token} = req.query

req.query 将是所有查询参数的对象。例如,如果您的 URL 是 https://domain.tld?q1=hello&q2=worldreq.query 将是 {q1: "hello", q2: "world"}


您应该通过发送响应来终止您的 HTTP 函数,否则它将 运行 保持 60 秒(或您的最大超时持续时间)并最终以该超时错误结束:

try {
  if (!data.success) {
    throw ({
      success: false,
      error: 'response not valid'
    })
  }
  res.status(200).json({data: data})
} catch (e) {
  console.log(e)
  res.status(500).json({error: e})
}

来自documentation,

Make sure that all HTTP functions terminate properly. By terminating functions correctly, you can avoid excessive charges from functions that run for too long. Terminate HTTP functions with res.redirect(), res.send(), or res.end().