【问题标题】:React and reCAPTCHA v3反应和 reCAPTCHA v3
【发布时间】:2018-12-18 12:20:42
【问题描述】:

是否有任何简单的方法可以在 react 中使用 reCAPTCHA v3?谷歌搜索只能找到 v2 的组件。并且只有 react-recaptcha-v3 用于 v3。

但是当我尝试使用该组件时,我收到一个错误 Invalid site key or not loaded in api.js。

【问题讨论】:

  • 你能发布你的实现代码吗?

标签: reactjs recaptcha


【解决方案1】:

嘿,你不需要一个包,它只是一个你不需要的不必要的包。 https://medium.com/@alexjamesdunlop/unnecessary-packages-b3623219d86 我写了一篇关于为什么你不应该使用它和另一个包的文章。 不要依赖某些软件包!改用谷歌:)

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>
)

【讨论】:

  • 谢谢 - 我正在尝试在没有包的情况下实现它。但是,尚不清楚如何实施您在此处发布的内容。这段代码去哪儿了?它何时被调用以及如何验证表单?您的代码中没有表格,我试图理解这段代码如何在没有表格的情况下做任何事情。我的理解是 v3 还需要服务器端调用,我在这里看不到任何内容。你能解释一下吗?
  • 很棒的回复和帖子。很多时候你发现有人只是链接一个 npm 包——经常自己做是最好的选择
  • 非常感谢您的代码示例。是的,你完全正确。在这种情况下,真的不需要 npm 包。
  • 能否分享更多关于如何使用这个组件(看起来像你概述了一个组件)的细节?例如:它如何与每个表单提交集成,例如登录或其他与表单相关的提交?我假设这些表单中的每一个都有不同的操作?
  • @YoungZaphod 我在提交函数中的handleLoaded then 中将代码发送到服务器。同样在UseEffect 不要写这行script.addEventListener("load", handleLoaded)
【解决方案2】:

我正在自学 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 方面的经验非常有限,但这个解决方案确实对我有用。我欢迎任何有关改进此代码的意见。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      您可以使用react-google-recaptcha3 npm 包(大小:~5 KB)

      npm i react-google-recaptcha3
      

      用法

      import ReactRecaptcha3 from 'react-google-recaptcha3';
      
      const YOUR_SITE_KEY = '';
      
      function App() {
       // load google recaptcha3 script
        useEffect(() => {
          ReactRecaptcha3.init(YOUR_SITE_KEY).then(
            (status) => {
              console.log(status);
            }
          );
        }, [])
      
      }
      

      现在在提交表单时,您需要生成令牌,然后将其附加到您的表单数据中

        const submit = () => {
          const formData = { name: "John", lastname: "Doe" }
          ReactRecaptcha3.getToken().then(
            (token) => {
              console.log(token);
              formData.token = token;
              // send request to backend
              fetch(url, { method: 'POST', body: JSON.stringify(formData) }).then(...)
              
            },
            (error) => {
              console.log(error);
            }
          );
        };
      

      现在在后端你需要验证令牌

      const request = require('request-promise');
      
      const secretKey = YOUR_RECAPTCHA_SECRET_KEY;
      const userIp = 'USER_IP';
      request.get({
          url: `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${recaptchaToken}&remoteip=${userIp}`,
      }).then((response) => {
      
          // If response false return error message
          if (response.success === false) {
              return res.json({
                  success: false,
                  error: 'Recaptcha token validation failed'
              });
          }
          // otherwise continue handling/saving form data
          next();
      })
      

      Stackblitz example

      【讨论】:

        猜你喜欢
        • 2021-11-04
        • 2019-09-22
        • 2022-01-19
        • 2018-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多