9
votes

Looks like the google recaptcha works in such a way that if a verification attempt has been made with a particular token, it cannot be used again.

Docs states that "you will need to call grecaptcha.reset() to ask the end user to verify with reCAPTCHA again"

I'm trying to attempt this using the react-google-recaptcha npm package.

Here is my code:

function onChange(grecaptcha) {
  console.log(grecaptcha);
  grecaptcha.reset(); // this doesn't work
}

class Captcha extends React.Component {
  render() {
    return <div>
      <Recaptcha
          sitekey='#'
          onChange={onChange(this)}
      /> </div> 
  }
}

When I tried to do the server side validations using the google api https://www.google.com/recaptcha/api/siteverify with response and secret value, the success response always evaluates to "false" after the first validation. To prevent this I'm resetting the grecaptcha as suggested in the docs but it doesn't work.

Anything that I'm missing?

Thanks in advance

EDIT:

https://github.com/dozoisch/react-google-recaptcha offers the reset() utility function which is what I'm trying to call after the user solves the captcha, wondering if I'm not calling it the right way.

6

6 Answers

7
votes

You can try Reaptcha.

It has more of a react-way approach in dealing with the reCAPTCHA than react-google-recaptcha.

Quoting the documentation:

<Reaptcha
  ref={e => (this.captcha = e)}
  sitekey="YOUR_API_KEY"
  onVerify={() => {
    // Do something
  }}
/>
<button onClick={this.captcha.reset}>
  Reset
</button>
10
votes

I was having a similar issue, and had to change it to:

window.grecaptcha.reset();
2
votes

First set up a suitably scoped variable for the element, then assign it using the ref callback:

let captcha;

<Recaptcha
  sitekey={sitekey}
  onChange={...}
  ref={el => { captcha = el; }}
/>

Then you're able to access the reset function by calling captcha.reset() when you need it (e.g. callback after successful message sent, registering etc.). Hope that helps.

2
votes

Well, this is just a bonus or a more elaborate way of all the above. I am using react-google-recaptcha so this is reactJS and not until I saw this that I found a way to solve the reset issue. It's rather straight forward. Am just explaining to mostly newbies like I think I am on how to do it just as pointed out by @sarneeh, @Chris and @AdityaSrivast

Here's my code snippet.

Captcha.js

import React from "react";
import ReCAPTCHA from "react-google-recaptcha";


const CaptchaVerify = ({yourprops}) => {

 let captcha;

 const onChange = (value) => {
    console.log(value);      
 }

 const setCaptchaRef = (ref) => {
    if (ref) {
      return captcha = ref;
    }
 };

 const resetCaptcha = () => {
   // maybe set it till after is submitted
   captcha.reset();
 }

 return (
   <ReCAPTCHA
     ref={(r) => setCaptchaRef(r) }
     sitekey={process.env.REACT_APP_V2_CAPTCHA_SITE_KEY}
     onChange={onChange, () => resetCaptcha()}
     theme="light"
   />
  )
 };

export default CaptchaVerify;
0
votes

google-react-recaptcha follows the syntax:

<ReCAPTCHA
    sitekey="Your client site key"
    onChange={onChange}
/>

You can reset by using reset() component instance. To access it you will need a ref.

Proceed like this:

<ReCAPTCHA
    ref={(r) => this.captcha = r}
    sitekey="Your client site key"
    onChange={onChange}
/>

Now whenever you want to reset the recaptcha, type in:

this.captcha.reset()

and you will be done.

Ideally, one should do it after the form submission, once you have got the response.

0
votes

Solution with functional component and createRef:

In function body:

  const recaptchaRef = React.createRef();

In JSX:

  <ReCAPTCHA
            ref={recaptchaRef}
            name="recaptcha"
            id="recaptcha"
            sitekey="...."
            onChange={(token)=>{console.log(token);}}
            onExpired={() => {
              recaptchaRef.current.reset(); // here
            }}
            theme="light"
          />