React and reCAPTCHA v3

时间:2018-12-18 12:20:42

标签: reactjs recaptcha

有什么简单的方法可以在react中使用reCAPTCHA v3吗?谷歌搜索过吗,只能找到v2的组件。而且只有v3的react-recaptcha-v3。

但是当我尝试使用该组件时,我得到一个错误的站点密钥或未加载到api.js中。

3 个答案:

答案 0 :(得分:22)

嘿,您不需要软件包,只是不需要的软件包。 https://medium.com/@alexjamesdunlop/unnecessary-packages-b3623219d86 我写了一篇文章,介绍了为什么不应该使用它以及另一个软件包。 不要依赖某些软件包!而是依靠google:)

const handleLoaded = _ => {
  window.grecaptcha.ready(_ => {
    window.grecaptcha
      .execute("_reCAPTCHA_site_key_", { action: "homepage" })
      .then(token => {
        // ...
      })
  })
}

useEffect(() => {
  // Add reCaptcha
  const script = document.createElement("script")
  script.src = "https://www.google.com/recaptcha/api.js?render=_reCAPTCHA_site_key"
  script.addEventListener("load", handleLoaded)
  document.body.appendChild(script)
}, [])

return (
  <div
    className="g-recaptcha"
    data-sitekey="_reCAPTCHA_site_key_"
    data-size="invisible"
  ></div>
)

答案 1 :(得分:0)

试试这个! https://github.com/t49tran/react-google-recaptcha-v3 npm install react-google-recaptcha-v3

但是说实话,我现在正在尝试...

最好的问候 真太郎

答案 2 :(得分:0)

我正在自学React + TypeScript,这就是我实现Recaptcha v3的构想。

我想要一个简单的解决方案,使我能够:

  • 仅在提交表单时动态获取令牌,以避免超时和重复的令牌错误
  • 出于隐私原因(例如登录,注册,忘记密码),仅在某些组件上使用recaptcha,而不是在index.html中全局定义recaptcha api.js
  • 需要最少的代码才能在组件中实现

reCAPTCHA.ts

declare global {
    interface Window {
        grecaptcha: any;
    }
}

export default class reCAPTCHA {
    siteKey: string;
    action: string;

    constructor(siteKey: string, action: string) {
        loadReCaptcha(siteKey);
        this.siteKey = siteKey;
        this.action = action;
    }

    async getToken(): Promise<string> {
        let token = "";
        await window.grecaptcha.execute(this.siteKey, {action: this.action})
            .then((res: string) => {
                token = res;
            })
        return token;
    }
}

const loadReCaptcha = (siteKey: string) => {
    const script = document.createElement('script')
    script.src = `https://www.recaptcha.net/recaptcha/api.js?render=${siteKey}`
    document.body.appendChild(script)
}

要使用此类,请将其声明为组件中的属性:

recaptcha = new reCAPTCHA((process.env.REACT_APP_RECAPTCHA_SITE_KEY!), "login");

然后在表单提交中获取您需要传递给后端的令牌:

let token: string = await this.recaptcha.getToken();

要在后端验证令牌:

recaptcha.ts

const fetch = require("node-fetch");
const threshold = 0.6;

export async function validateRecaptcha(recaptchaToken: string, expectedAction: string) : Promise<boolean> {
    const recaptchaSecret = process.env.RECAPTCHA_SECRET_KEY;
    const url = `https://www.recaptcha.net/recaptcha/api/siteverify?secret=${recaptchaSecret}&response=${recaptchaToken}`;
    let valid = false;
    await fetch(url, {method: 'post'})
        .then((response: { json: () => any; }) => response.json())
        .then((data: any)=> {
            valid = (data.success && data.score && data.action && data.score >= threshold && data.action === expectedAction);
        });
    return valid;
}

我对JS / TS和React的经验非常有限,但是此解决方案确实对我有用。我欢迎您提供任何有关改进此代码的意见。