springload / wagtail-django-recaptcha

A simple recaptcha field for Wagtail Form Pages
https://pypi.python.org/pypi/wagtail-django-recaptcha/
MIT License
56 stars 20 forks source link

reCAPTCHA v3 #33

Open gregcowell opened 3 years ago

gregcowell commented 3 years ago

I notice that django-recaptcha supports reCAPTCHA v3. Any plans to support this version in wagtail-django-recaptcha? I tried following the django-recaptcha instructions for configuring reCAPTCHA v3 (adding a captcha field to my form with the v3 widget) but I suspect the client side code in wagtail-django-recaptcha needs to support this for it to work.

ar4s commented 2 years ago

You can use a custom form builder like this:

from captcha.fields import ReCaptchaField
from captcha.widgets import ReCaptchaV3
from wagtailcaptcha.forms import WagtailCaptchaFormBuilder
from wagtailcaptcha.models import WagtailCaptchaEmailForm

class CustomFormBuilder(WagtailCaptchaFormBuilder):
    @property
    def formfields(self):
        fields = super(WagtailCaptchaFormBuilder, self).formfields
        fields[self.CAPTCHA_FIELD_NAME] = ReCaptchaField(label="", widget=ReCaptchaV3())
        return fields

class FormPage(WagtailCaptchaEmailForm):
    form_builder = CustomFormBuilder
enzedonline commented 2 years ago

@ar4s Hi Arkadiusz,

Was there anything else needed to get v3 working aside form your snippet above?

I tried to implement it on my dev site (v2 working fine), changed keys to v3 keys (localhost added to domains). I see the 'Protected by Captcha' slider in the bottom right, all the code for the captcha above the submit button, but no captcha displays.

Tried adding the api.js to the header, no change. <script type="text/javascript" src="https://www.google.com/recaptcha/api.js" async defer></script>

Aman-garg-IITian commented 11 months ago

@enzedonline have you figured it out as mine also not working

enzedonline commented 10 months ago

@Aman-garg-IITian no, I put this onto a to-do list for now. It's a hard one to troubleshoot since v3 captchas don't display, it's a hidden control. I do need to find a solution though, v2 captcha is kind of useless these days, my sites get flooded with Russian bot spam these last few months.

enzedonline commented 10 months ago

@Aman-garg-IITian I revisited this again, set it up from scratch and now have it working. I can only guess there was some fundamental mistake I'd been making in last iteration. The above solution is correct in getting it working, however there is a change needed - Recaptcha tokens have a 2 minute lifetime. With V2, this starts when the user clicks the captcha checkbox. With the above solution, the key is loaded on page load. By the time the user fills in the form, it can be expired already.

The solution is that the challenge should be bound to the form submit as per google docs.

The form builder needs a bit of a rewrite to accommodate this.

Aman-garg-IITian commented 10 months ago

@enzedonline i tried this and filled the form faster just for testing purpose but still i couldn’t see any change in the captcha v3 admin dashboard to verify if its working. it didn’t work, is the part where you are including api.js to the header also required?

enzedonline commented 10 months ago

@Aman-garg-IITian I think it takes a while before Google collates the report.

Note: The scores for this site may not be accurate before running with sufficient live traffic. Please see our developer site for more information.

I didn't need to add api.js to the head in the end, once I'd set this up correctly, this gets added inline automatically:

<script src="https://www.google.com/recaptcha/api.js?render=xxx"></script>

enzedonline commented 10 months ago

There's a new version of django-recaptcha out today, this fixes the V3 timeout issue. https://github.com/torchbox/django-recaptcha/discussions/319

The namespace has changed so it's worth reading the changelog before updating. It does break the import on wagtailcaptcha/forms.py line 4:

from captcha.fields import ReCaptchaField needs updating to from django_recaptcha.fields import ReCaptchaField