Captcha verification failed
I keep getting "Captcha verification failed" after adding Cloudflare Turnstyle captcha using Nextjs:
4 Replies
In RegisterForm:
In lib/auth.ts:
lib/auth-client.ts:
Envs are defined like so in both .env.local and regular .env file
:
CLOUDFLARE_TURNSTILE_SECRET_KEY=.....
NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY=......
It is basically throwing a 403:
POST /api/auth/sign-up/email 403 in 145ms
Hey! Same here, very similar setup (Next.js etc). I'll let you know if I solve it
This is the problem area. The
I also added form validation to confirm that "turnstileToken" has a value if the user submits before the automated check from Turnstile is complete (or if it decides they need to interactively click and they haven't yet). So we block on the client until the token has been set. To summarize how it works: when the Cloudflare widget runs it confirms the user is not a bot and then gives you a token. You then pass that token to your server via the headers. The Better Auth plugin will then call Cloudflare's
x-captcha-response
needs to be set to the value that the Turnstile widget gets back from Cloudflare.
I think there are a couple ways of using react-turnstile, but I do it with the onSuccess
callback. Your siteKey is fine but you can add onSuccess.
setTurnstileToken
is pointing back to state defined with useState
in the component. In your case you would pass turnstileToken
to your RegisterForm and then use that string as the value for x-captcha-response
. Alternately, add the Tunstile component right within your register form instead and then handle the state internally in the form component.I also added form validation to confirm that "turnstileToken" has a value if the user submits before the automated check from Turnstile is complete (or if it decides they need to interactively click and they haven't yet). So we block on the client until the token has been set. To summarize how it works: when the Cloudflare widget runs it confirms the user is not a bot and then gives you a token. You then pass that token to your server via the headers. The Better Auth plugin will then call Cloudflare's
siteverify
endpoint from the server to check the validity of the token it got from the client. CF will confirm it's a valid token and your server will then proceed, knowing that it's a real user.Great digging! Thanks Erik, will explore this later this week. Appreciate your time + thorough writeup