How do I add Captcha to RedwoodJS?

Hello everyone, could you please help me by telling me how can I add captcha for login, register etc. I am using dbAuth authentication. Thank you :blush:

Hi @Parcero I don’t currently see an open feature request for adding a Captcha to dbAuth.

I have seen other auth systems use HCapthcha https://www.hcaptcha.com/ so that may help with some implementation options and explain how they work.

Please do write up an issue for the feature and if you would like to help on a PR that’s always very welcome.

hcaptcha verifies the token in the backend but you can’t pass parameters to loginOptions to write the token verification logic to avoid bots, any ideas?

@rob do you have an idea of what it might take to add Captcha validation to dbAuth? Is there some pre sign up or login hook?

So in the handler() functions for signup and login in api/src/functions/auth.js you could put whatever additional logic you want before actually creating an account or letting someone log in.

In the signup one, you get a fourth userAttributes argument that will contain any additional fields that were present on the signup page besides username and password. This could be your captcha value that you then make an API call to verify.

With login it’s a little more difficult, as you don’t have access to any additional fields. You could potentially put the captcha value in a cookie, and then read that same cookie on the server side in the login handler() function.

Does that help?

1 Like

Thanks a lot

1 Like

@Parcero If you do get an example working, please do share and we can post in Solutions – or even better, add to the dbAuth docs.

I’m sure your work will help others a ton.

Thanks!

ok.

install on the web:
https://github.com/hCaptcha/react-hcaptcha
https://github.com/reactivestack/cookies/tree/master/packages/universal-cookie

on the login page import:

import HCaptcha from '@hcaptcha/react-hcaptcha'
import Cookies from 'universal-cookie'

inside the LoginPage arrow function add:

const [token, setToken] = React.useState(' ')
const captchaRef = React.useRef(null)
const cookies = newCookies()

inside the onSubmit arrow function add:

captchaRef.current.resetCaptcha()
if (!token) return toast.error('Captcha is required')
cookies.set('captcha', token, { path: '/' })
const response = await logIn({ ...data })
cookies.remove('captcha', { path: '/' })

add the hcaptcha component for example at the top of the submit button:

<HCaptcha
  sitekey="30000000-ffff-ffff-ffff-000000000003"
  onVerify={setToken}
  ref={captchaRef}
/>

The site key and secret key would be better in the environment variables and you get them when registering on the hcaptcha page, but you can also use the test keys they provide https://docs.hcaptcha.com/

install in api:
https://github.com/vastus/node-hcaptcha
https://github.com/reactivestack/cookies/tree/master/packages/universal-cookie

in api/src/functions/auth import:

import { verify } from 'hcaptcha'
import Cookies from 'universal-cookie'

inside the handler() in loginOptions:

const cookies = new Cookies(event.headers.cookie)
const captcha = cookies.get('captcha')
if (!captcha) throw new Error('Captcha is required')
const response = await verify(
 '0x0000000000000000000000000000000000000000',
 captcha
)
if (!response.success) throw new Error('Verification failed')

Screenshot_7

2 Likes

if you don’t want to install universal-cookie on web and api


Screenshot_9

2 Likes

Interesting @Parcero.

Question: How is cookies.splt("=").[1].trim the captcha cookie and not session? Is there a way to get the cookie by captcha name?

Edit: Oh --I see in the previous post, the universal cookie can reference by name “captcha”.

Nice!

1 Like

Well if we wanted to search for the captcha cookie without the need to install dependencies, I think it would be like this
Screenshot_11

Awesome! Glad to see you got this working!

1 Like