Cloudflare Turnstile Spam Bot Protection

If you have public-facing forms, such as a contact form or a newsletter signup form, then you'll probably want to protect those forms from receiving spam (bot) form submissions.

A popular tool for this is Cloudflare Turnstile, a popular alternative to Google's reCAPTCHA, which provides a widget (visible or invisible) to protect any form from receive spam submissions. The Cloudflare Turnstile implementation uses the railscloudflareturnstile gem.

The Cloudflare Turnstile component is automatically installed and implemented for you when you install the Contact Form component or the Kit (ConvertKit) component.

Or you can install it manually and implement it on any form using the instructions below.

Installation

Copy
rails g instrumental:cloudflare_turnstile

After installation, find the file config/initializers/cloudflare_turnstile.rb and uncomment the initializer code.

Configure Cloudflare Turnstile

Log into your Cloudflare account and configure your Cloudflare Turnstile widget here.

For “hostname”, add your production domain name.

In your Rails project, edit your Rails credentials, and add the following to them.

The first two lines should have your Cloudflare Turnstile site key and secret key.

Copy
cloudflare:
# turnstile_site_key: your_production_site_key
# turnstile_secret_key: your_production_secret_key

# The following test scenarios use keys found here:
# https://developers.cloudflare.com/turnstile/troubleshooting/testing/

# Test keys: Widget is visible, always passes
  turnstile_site_key: 1x00000000000000000000AA
  turnstile_secret_key: 1x0000000000000000000000000000000AA

# # Test keys: Widget is invisible, always passes
# turnstile_site_key: 1x00000000000000000000BB
# turnstile_secret_key: 1x0000000000000000000000000000000AA

# # Test keys: Widget is visible, always fails
# turnstile_site_key: 2x00000000000000000000AB
# turnstile_secret_key: 2x0000000000000000000000000000000AA

# # Test keys: Widget is invisible, always fails
# turnstile_site_key: 2x00000000000000000000BB
# turnstile_secret_key: 2x0000000000000000000000000000000AA

# # Test keys: Widget forces a challenge
# turnstile_site_key: 3x00000000000000000000FF
# turnstile_secret_key: 1x0000000000000000000000000000000AA

Testing Cloudflare Turnstile in local development environment

When you’re in your local environment, you can leave your own keys commented out (or remove them) and then uncomment one set of keys from the selection of test keys. All of the testing scenarios that Cloudflare provides here have been included for you. Just uncomment the set that you want to test (and comment out the rest).

Usage

Follow these steps:

This is an example of a controller that manages the Contact form page and form submission:

Copy
class ContactController < ApplicationController
  allow_unauthenticated_access

  before_action :validate_cloudflare_turnstile, only: [:contact_form_submission]
  rescue_from RailsCloudflareTurnstile::Forbidden, with: :handle_turnstile_error

  def index; end

  def contact_form_submission
    ContactMailer.contact_form_email(
      name: params[:name],
      email: params[:email],
      subject: params[:subject],
      message: params[:message],
      page_url: request.referer
    ).deliver_later

    redirect_to contact_path(sent: true)
  end

  private

  def handle_turnstile_error
    redirect_to contact_path, alert: "Something went wrong. Please try again."
  end
end

In the view that contains the form, add this line. This will activate the Cloudflare script that Instrumental Components installed into your application's head.

Copy
<% content_for(:require_cloudflare_turnstile_script, true) %>

Finally, inside of your form block, add the following line, which renders the Cloudflare Turnstile widget.

Copy
<%= cloudflare_turnstile %>

That's it! You can now test your form in your local environment (assuming you have the test keys uncommented in your credentials) and see the Cloudflare Turnstile widget in action. You should also test it in your production environment.

Instrumental Components

I created Instrumental Components to make designing and building professional apps with Ruby on Rails easy, fast, and fun. I use it on all of my projects and I hope it helps you build something great.

Brian Casel
Brian Casel
Creator of Instrumental Components
Learn more Send me a question or request