Jump to content

Comments module with Cloudflare Turnstile


millipedia
 Share

Recommended Posts

We're building a site that's going to be using the Comments Module and I'm looking at ways to mitigate the amount of spam I'm expecting.

Alongside the usual honeypot / Akismet solutions I was thinking of using Cloudflare's Turnstile captcha doodah.

I was thinking of either just not rendering the form until the Turnstile challenge was completed or hooking into the Comments module to validate the Turnstile token, or hell, maybe both.

Has anyone done something like this already? It's not obvious to me how to hook into a Comment submission - so if anyone can point me in the right direction that would be a good start.

Link to comment
Share on other sites

I kinda tried this and gave up lol but here's what I found:

You'd probably start with the CommentFormCustom class:

https://github.com/processwire/processwire/blob/master/wire/modules/Fieldtype/FieldtypeComments/CommentFormCustom.php

The first comments have a little bit on how these could be used. I THINK, that something not covered is upadting the processing of the comment, so my guess is that you could implement your own "CommentFormMillipedia" for example, extending CommentForm just like CommentFormCustom, and override the processInput method, so you could process additional stuff, aside from the form fields.

Although from reading the code you'd probably have to copy the whole FieldytpeComment module due to the way ComentFormCustom class is loaded

To be honest it was a bit suprised to see the comment form is not built with the Inputfields API! Maybe to allow more simplicity on the rendering?

  • Like 1
Link to comment
Share on other sites

OK - this kind of works:

In my template I've included the Cloudflare script (and added their end point to the content security policy). Then I'm injecting a placeholder into the form:

$comments_form= $page->comments->renderForm(array(
      'requireHoneypotField' => 'email2'
       ));

// add a div with class="cf-turnstil" to the form - this gets replaced with a token (after a successful challenge)
$cft_tag='<div class="cf-turnstile" data-sitekey="yourturnstilesitekey"></div>';
$comments_form=str_replace("CommentForm' method='post'>","CommentForm' method='post'>$cft_tag", $comments_form);

echo $comments_form;

Cloudflare replaces that with  a token if they think you're not a bot.

Then in init.php (not _init.php) I'm hooking into ProcessPageVIew

$this->addHookBefore('ProcessPageView::execute', function(HookEvent $event) {

	if(wire('input')->post('CommentForm_submit')){

                // get the Cloudflare token.
                $cf_token=wire('input')->post('cf-turnstile-response');

                // and send it to siteverify 
                $postdata = http_build_query(
                array(
                        'secret' => 'yoursupersecretcloudflaresecretkey',
                        'response' => $cf_token
                )
                );

                $opts = array('http' =>
                array(
                    'method'  => 'POST',
                    'header'  => 'Content-Type: application/x-www-form-urlencoded',
                    'content' => $postdata
                )
            );

                $context  = stream_context_create($opts);

                $api_json_response = file_get_contents('https://challenges.cloudflare.com/turnstile/v0/siteverify', false, $context);

               if($api_json_response ){

                        // check result and redirect if failed.
                        $result=json_decode($api_json_response,TRUE);

                        if(!($result['success'])){
                                // die or redirect or whaterver you fancy.
								// print_r($result);
								// die("Failed verification.");
								wire('session')->redirect('/some-help-page-or-something/'); 
                            
                        }
               }else{
                        // die or redirect or whaterver you fancy.
						die("No response from verification server.");
               }

	}
  

  });

If we have a comment that's been submitted then I check the token with Cloudflare. If it fails we can redirect or die or something - it'd be nice to fail a bit more gracefully.

No idea how well this will deal with spam and I think I'll need to do some user testing but I think it might be useful.

  • Like 2
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...