使用Redux表单实现不可见的reCAPTCHA

csm*_*csm 10 recaptcha reactjs redux-form

我正在尝试使用React和Redux Form 实现Invisible reCAPTCHA.通常,Invisible reCAPTCHA工作流程是:

  1. 渲染"不可见"CAPTCHA,返回其小部件ID.
  2. grecaptcha.execute使用小部件的ID 调用.如有必要,将提示用户解决挑战.结果将传递给呈现CAPTCHA时指定的回调函数.
  3. 提交表格和CAPTCHA结果.

我已经创建了一个React组件,旨在与Redux Form一起使用,Field它会在grecaptcha.execute调用后呈现CAPTCHA并更新表单状态:

class ReCaptcha extends React.Component {
  render() {
    return <div ref={div => this.container=div} />
  }

  componentDidMount() {
    const { input: { onChange }, sitekey } = this.props
    grecaptcha.render(this.container, {
      sitekey,
      size: "invisible",
      callback: onChange
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,我不知道grecaptcha.execute在用户提交表单时如何或在何处与小部件ID一起调用.我无法调用它,onSubmit因为那里无法访问小部件ID.我可以ReCaptcha在渲染CAPTCHA之后立即调用它,但是如果用户需要解决CAPTCHA,一旦表单呈现就会提示他这样做.

这个最小的工作示例显示了我迄今取得的成就.

Twi*_*uff 1

使用 onSubmit 属性调用 grecaptcha.execute(),并将数据回调指向“真实”onSubmit 函数。

let refToMyWidget;
const { handleSubmit } = this.props;

componentDidMount() {
  if (window.grecaptcha) {
    refToMyWidget = window.grecaptcha.render(this.container, {
      sitekey: "xxxx",
      size: "invisible",
      callback: handleSubmit(this.actuallySubmit)
    })
  }
}

preSubmit() {
  if(!window.grecaptcha) {
    return;
  }
  window.grecaptcha.execute(this.refToMyWidget)
}

actuallySubmit() {
  // submission logic here
}

render() {
  return (
    <form onSubmit={handleSubmit(this.preSubmit)}>
        <Field name="foo" component="input" />
        <button>Submit</button>
    </form>
  )
}
Run Code Online (Sandbox Code Playgroud)

注意,我还没有测试过这段代码,但它应该或多或少是正确的。如果您在将 grecaptcha 加载到页面/表单时遇到问题,我发现这段代码非常有帮助。