使用Firebase和reCAPTCHA

35

令人惊讶的是,尽管两者均为Google产品,但我无法找到有关如何将Recaptcha与Firebase集成的任何信息。 这是否可能? 如果不行,那么我在Firebase应用程序中没有验证权限时可以使用什么来验证用户?


我目前也在研究这个问题。等我有了答案或者更新,会及时回来告诉你。 - Kieran Hall
我还没有开始解决方案,但是我打算使用Firebase的Cloud Functions(https://firebase.google.com/docs/functions/)来与Recaptcha集成。这里有类似的用例:https://github.com/firebase/functions-samples。 - Kieran Hall
我不知道是否晚了。现在有 Firebase 的云函数。你可以在它上面用 JavaScript 编写自己的后端 API。不需要直接从客户端调用 Firebase 数据库,你可以通过 Firebase 的云函数调用自定义 API 并在客户端进行 reCaptcha 验证,并作为管理员(firebase-admin)对数据库进行操作。我尝试过,效果很好。 - pupuupup
1
这是我所做的流程... 1)使用reCaptcha验证客户端不是机器人 2)将令牌与post数据一起发送到自定义云函数API 3)在云函数中验证reCaptcha令牌 4)作为管理员更新Firebase数据库中的数据。(安全规则可以是.write:false,云函数将能够以“firebase-admin”身份写入它,只有通过reCaptcha身份验证的客户端才能写入它) - pupuupup
2个回答

26

这篇文章已经比较老了,但是以下的答案可以帮助像我一样通过Google搜索找到这篇文章的人。现在它已经内置并且设置非常简单:

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha', {
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
})
window.recaptchaVerifier.render()

正如tuananh所提到的,确保你添加一个<div id="recaptcha"></div>


1
避免异常 "Error: reCAPTCHA容器未找到或已包含内部元素"。请添加id="recaptcha"的元素,例如:<div id="recaptcha"></div>。 - tuananh
3
我想指出的是,此方法使用的是“firebase.auth”,不适用于服务器端身份验证或Node.js实现。它只适用于客户端JavaScript项目中的“内置”。Doug Stevenson上面介绍的方法对于任何进行服务器端渲染的人都是必要的。例如,如果您想让Firebase函数在将用户输入发送到另一个使用管理员SDK创建新用户帐户的函数之前验证验证码。 - Matthew Rideout
1
我找不到如何使用signInWithEmailAndPassword使其工作,它没有等待appVerifier的第三个参数,就像signInWithPhoneNumber一样。 - leoxs

11

我刚刚发布了一篇关于如何在网站中使用Firebase Hosting来提供内容,以及使用Firebase Cloud Functions来验证从reCAPTCHA收到的响应的教程博客。假设响应令牌通过查询字符串接收,那么函数本身看起来像这样:

const functions = require('firebase-functions')
const rp = require('request-promise')

exports.checkRecaptcha = functions.https.onRequest((req, res) => {
    const response = req.query.response
    console.log("recaptcha response", response)
    rp({
        uri: 'https://recaptcha.google.com/recaptcha/api/siteverify',
        method: 'POST',
        formData: {
            secret: 'PASTE_YOUR_SECRET_CODE_HERE',
            response: response
        },
        json: true
    }).then(result => {
        console.log("recaptcha result", result)
        if (result.success) {
            res.send("You're good to go, human.")
        }
        else {
            res.send("Recaptcha verification failed. Are you a robot?")
        }
    }).catch(reason => {
        console.log("Recaptcha request failure", reason)
        res.send("Recaptcha request failed.")
    })
})

1
有没有使用request promise的替代方案。const rp = require('request-promise') - Gal Bracha
如果我想在允许用户使用Facebook或Google OAuth之前使用它怎么办? - Gal Bracha
2
你可以使用任何HTTP客户端库,只要遵循reCAPTCHA API规范即可。同时,你可以在任何时间完成它。 - Doug Stevenson
我应该如何格式化tan http请求,而不是使用window.location?这个请求会是什么样子? - SeanMC
1
这个在 web 应用中怎么运作呢?如果我在注册之前调用这个函数,人们可以直接绕过它去注册,使得 recaptcha 调用毫无意义。你需要将电子邮件和密码从客户端发送到这个函数,并且只有在 recaptcha 成功通过后才能在服务器端进行注册,才能让这个函数变得可信。 - SeriousLee
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接