nbcommunication Posted September 27 Share Posted September 27 This module allows you to add Cloudflare's Turnstile CAPTCHA to your website, providing a user-friendly alternative to Google's reCAPTCHA. It is based on MarkupGoogleRecaptcha, allowing for easy switching between the two CAPTCHA systems. If MarkupGoogleRecaptcha is installed, some of its settings are used to configure Turnstile. https://github.com/nbcommunication/MarkupCloudflareTurnstile We've used reCAPTCHA for many years now but have found that it isn't as effective as it should be in reducing spam. It is also pretty annoying. We've recently switched a couple of our 'bigger' sites to use Turnstile (using this module) as the sites were on Cloudflare already. It is definitely a much friendlier captcha for users, still to determine whether it is better at preventing spam, but I expect it will be. Cheers, Chris 5 3 Link to comment Share on other sites More sharing options...
Kiwi Chris Posted September 27 Share Posted September 27 Thanks for this. It probably shouldn't be too hard to adapt Ryan's InputfiledFormBuilderRecaptcha to use Cloudflare as well. I just read an article today stating that bots can now defeat pretty much all of those visual captchas that ask to identify what squares contain a given object, so this is quite timely. 1 Link to comment Share on other sites More sharing options...
JayGee Posted October 4 Share Posted October 4 This is fantastic thank you 🙏. Building this exact integration for ProcessWire has been on our backlog a while - excited to give it a try. Link to comment Share on other sites More sharing options...
JayGee Posted December 12 Share Posted December 12 Hi all, I've been doing some work to extend this great module created by @nbcommunication to meet a specific need we have. This is very much as-yet untested in production, but I wanted to share it here now anyway in case anyone wants to point out any flaws in the logic, try out the changes or suggest improvements before we push it to any live sites or make a PR to NB. The challenge: We manage a number of sites where we would like to get forms behind Turnstile. But in many cases these forms are connected to or hosted by third-party CRMs/Email marketing platforms etc which makes integrating Turnstile tricky and time consuming. The proposed solution: Rather than modifying a plethora of different third-party form integrations 1-by-1 and verifying submissions with Cloudflare on submit, we'll remove the forms from the DOM and only render them once Turnstile verifies the site visitor. As mentioned this is as-yet untested so I've no idea how robust this will be against bots and scrapers, but it seems worth trying IMO! In case people are wondering why we wouldn't use Cloudflare's other bot mitigation tools - we don't control all site's DNS and not all sites run behind Cloudflare. Turnstile works regardless of whether the site uses Cloudflare nameservers. The approach: I've modified the Turnstile module with a few new methods to do the following: Utilises @ryan's awesome URL hooks to create some endpoints to handle Turnstile token verification and: Dynamic loading of HTML render files into a page only once the token is verified. Use of data-attributes in page elements to specify the target location and file for rendering. Forked branch available here: https://github.com/warp-design/MarkupCloudflareTurnstile/tree/feature-protect-content-turnstile All probably best illustrated visually: Example page structure using a mix of the existing module methods and the new ones: <body> <?php //Load module in page $captcha = $modules->get('MarkupCloudflareTurnstile'); ?> <!-- Existing module widget render call. Set inside #turnstile-container to auto hide turnstile after verification --> <div id="turnstile-container"> <?= $captcha->render(); ?> </div> <!-- Elements you wish to protect with Turnstile. Set data attribute with render file path, relative to templates folder. There divs will populate with the specified render files when Turnstile verifies. --> <div class="turnstile_content" data-render-path="inc/exampleForm"></div> <div class="turnstile_content" data-render-path="inc/exampleContent"></div> <!-- New method to load the scripts if you want to protect dom elements behind Turnstile --> <?= $captcha->renderProtectedContent(); ?> <!--Existing module script call--> <?= $captcha->getScript(); ?> </body> And how this page looks live. Note: .turnstile_content elements only populate when Turnstile is verified: Test - 11 December 2024 - Watch Video Let me know what you think - is this a workable approach, or am I overlooking pitfalls? Likely issues/TODOs you may encounter: Things may need more sanitization and better error handling to come out during testing. Not sure how this will behave when loading in external JS. I've tried to ensure it will initialise any scripts in the render files when they are loaded. In theory things shouldn't be too different to loading content with frameworks or something like HTMX. Would be nice to eventually add support for passings $vars and $options params to the render files like any other PW template call. Someone may have already implemented the above in another module and I hadn't noticed! 😅 Link to comment Share on other sites More sharing options...
nbcommunication Posted December 17 Author Share Posted December 17 Hi @JayGee, My main concern with this approach would be usability for users that are the opposite of bots - e.g. older, less tech savvy users ("I tried to but I couldn't see the form") - but I think a text prompt with the captcha would remedy this. There might also be issues with cumulative layout shift, if this is a concern then rendering a placeholder of the size of the rendered form with the captcha sitting on top of that might solve that. What I would say is that if I were developing this, I probably wouldn't piggy back on this module and instead use it as a reference for another module written from scratch. This module is just a turnstile version of the MarkupGoogleRecaptcha module, built to facilitate an easy switch from using reCAPTCHA to Turnstile. That said, if it does what you need it to do for your use case then that's great! I do like the idea of only rendering the form once the captcha has been passed though, I'm sure there must be some UX research / opinion about this but couldn't find any with a quick search. Do let us know how you get on! Cheers, Chris Link to comment Share on other sites More sharing options...
JayGee Posted December 17 Share Posted December 17 10 minutes ago, nbcommunication said: Hi @JayGee, My main concern with this approach would be usability for users that are the opposite of bots - e.g. older, less tech savvy users ("I tried to but I couldn't see the form") - but I think a text prompt with the captcha would remedy this. There might also be issues with cumulative layout shift, if this is a concern then rendering a placeholder of the size of the rendered form with the captcha sitting on top of that might solve that. What I would say is that if I were developing this, I probably wouldn't piggy back on this module and instead use it as a reference for another module written from scratch. This module is just a turnstile version of the MarkupGoogleRecaptcha module, built to facilitate an easy switch from using reCAPTCHA to Turnstile. That said, if it does what you need it to do for your use case then that's great! I do like the idea of only rendering the form once the captcha has been passed though, I'm sure there must be some UX research / opinion about this but couldn't find any with a quick search. Do let us know how you get on! Cheers, Chris Hi Chris, Thanks for your input. We were also concerned about cumulative layout shift - but I think this can be fixed by setting heights on placeholders etc. We were focussed only on solving the immediate problem in hand... bots!! I've also thought we could have a dummy form with the same fields etc but no logic/action and switch them out following validation. FWIW it seems to be working so far too 🤞. In terms of UX - yes we were unsure if this was really the 'right thing' to do - but in my opinion it's not to dissimilar in approach to Cloudflare's standard bot mitigation approach where the whole page is prevented from rendering. I think for ease and speed of deployment to address specific issues, the trade-offs are worth it. We'll keep this forked as a separate module for the moment. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now