executeAsync can only be called once
I use the executeAsync. The first time i call it there is no problem and i receive a token. But the second time the call hangs and i dont get a token nor an error.
i created a codepen that reproduces the behavior: https://codesandbox.io/s/react-google-recaptcha-210-example-invisible-forked-wkk89?file=/src/index.js:441-453
Not that after the first call "onSubmitAsync" is printed, but the executeAsync never returns.
If i would call reset afterwards it works, but i reckon i get to many puzzles to solve with a reset. Plus the reset is visible in the UI.
react-google-recaptcha version: 2.1.0 react-async-script version: 1.2.0
@MethodenMann Thanks for the detailed and informative issue. And THANK YOU for the codesandbox.io example!
I was able to dig into this a bit. There is definitely some sort of internal "throttle" to the grecaptcha.execute command. Google apparently doesn't want their systems spammed for tokens/responses.
Both of react-google-recaptcha's methods execute and executeAsync have the same issue with this "throttling".
But there is a method on the google recaptcha object itself that can give you the recaptcha's current valid response/token grecaptcha.getResponse.
- https://developers.google.com/recaptcha/docs/invisible#js_api
react-google-recaptcha exposes this api via our getValue method.
https://github.com/dozoisch/react-google-recaptcha/blob/5ec0e2fa9b492f338f82a59755b735840d9f348a/src/recaptcha.js#L13-L16
Let me know if this is something you can use to help solve your use case.
Cheers.
Sorry it took me so long to get back to this.
Our client generates the token and then does a login request with this token. If the request fails and the user tries another password, a new token should be created for further login attempts.
We could use getValue to get the current valid token for further requests. But the problem is, that this token is already verified in the backend and therefore not valid anymore. A token can only be verified once once to prevent replay attacks (https://developers.google.com/recaptcha/docs/verify)
So it would really be neat to just get a new token on the client site. The only other solution i can think of, is to remember a valid token verification in the backend.
Hope i did explain the problem properly.
You can run grecaptcha.reset() to reset the recaptcha so that you don't need to wait until you can call grecaptcha.execute() again.
Bump
@hafezoa seems like the last comment in the thread answers the question. If you've tried what azinod is suggesting and it doesn't work please provide information about it.
@dozoisch it doesn't work..
I found only one solution to remove react element from DOM and reinit again:
initForm() {
setIsRecaptchaEnable(true);
}
onCaptchaUpdate() {
setIsRecaptchaEnable(false);
}
{ isRecaptchaEnable &&
<reCaptcha ... />
}
I had a similar problem. @ScriptArtist's solution seems to work.
one problem is that recaptcha continually creates a new a div element in the background.
Actually the solution of @azinod seems to work pretty well.
https://codesandbox.io/s/react-google-recaptcha-210-example-invisible-forked-u35ii
Just wanted to share that @azinod 's answer also works for executeAsync()!
The recaptcha ref is null after ref.current.executeAsync(). The executeAsync call returns a token but it throws if I try to do ref.current.reset() after it as I am now trying to access property of null.
Any suggestions?
Not sure, but I think you have to use useCallback for update your ref when re-sumit…
Example:
const recaptchaRef = createRef()
const onSubmit = useCallback(async () => {
const token = await recaptchaRef.current?.executeAsync()
recaptchaRef.current?.reset()
}, [recaptchaRef])