PetToys.CloudflareTurnstileNet 1.2.1

Prefix Reserved
dotnet add package PetToys.CloudflareTurnstileNet --version 1.2.1                
NuGet\Install-Package PetToys.CloudflareTurnstileNet -Version 1.2.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PetToys.CloudflareTurnstileNet" Version="1.2.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PetToys.CloudflareTurnstileNet --version 1.2.1                
#r "nuget: PetToys.CloudflareTurnstileNet, 1.2.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install PetToys.CloudflareTurnstileNet as a Cake Addin
#addin nuget:?package=PetToys.CloudflareTurnstileNet&version=1.2.1

// Install PetToys.CloudflareTurnstileNet as a Cake Tool
#tool nuget:?package=PetToys.CloudflareTurnstileNet&version=1.2.1                

Cloudflare Turnstile for NET

Unit Test NuGet Version NuGet Downloads

Based on the following project

Provided under the Apache License, Version 2.0.

Requirements

You must have a CloudFlare account. Create a Turnstile widget for your form or site. You will need the SiteKey and SecretKey.

Installation

You can install this package using NuGet.

# Package Manager
PM> Install-Package PetToys.CloudflareTurnstileNet

# .NET CLI
dotnet add package PetToys.CloudflareTurnstileNet

Configuration

Create a new configuration section like this in your appsettings.json and update the SiteKey and SecretKey values from CloudFlare.

{
  "CloudflareTurnstileOptions": {
    "SiteKey": "Site key from your CloudFlare dashboard",
    "SecretKey": "Secret key from your CloudFlare dashboard",
    "Enabled": true
  },
}

Usage

To use PetToys.CloudflareTurnstileNet in your project, you must add the CloudflareTurnstileNet services to the service container like so:

builder.Services.AddCloudflareTurnstile(builder.Configuration.GetSection("CloudflareTurnstileOptions"));

Clientside Code

The cloudflare turnstile javascript must be added as well as the turnstile div. In automatic mode the asp-validation-summary is also required to show the validation error.

An example razor page:

@page
@namespace MyApp.Pages
@using Microsoft.Extensions.Options
@using PetToys.CloudflareTurnstileNet
@inject IOptions<CloudflareTurnstileOptions> turnstileOptions
@model ContactModel
<!DOCTYPE html>
<html lang="en">
<head>
  @if (turnstileOptions.Value.Enabled)
  {
    <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" defer></script>
  }
</head>
<body>
  <form method="POST">
    <h1>Contact Us</h1>
    <div asp-validation-summary="ModelOnly" class=""></div>
    <textarea asp-for="Message"></textarea>
    <span asp-validation-for="Message"></span>
    @if (turnstileOptions.Value.Enabled)
    {
      <div class="cf-turnstile" data-sitekey="@turnstileOptions.Value.SiteKey"></div>
    }
    <input type="submit" name="submit" value="Send" />
  </form>
  
</body>
</html>

Automatic Validation

Automatic verification can be applied by adding an attribute to your page model or controller. Here is a razor page example that uses FormErrorMessage to set a custom error message:

using PetToys.CloudflareTurnstileNet;

[ValidateCloudflareTurnstile(FormErrorMessage = "Cloudflare Turnstile verification failed")]
public class ContactModel : PageModel
{

For an MVC controller apply the attribute to the action method:

[HttpPost]
[ValidateCloudflareTurnstile(FormErrorMessage = "Cloudflare Turnstile verification failed")]
public IActionResult Submit(ContactViewModel model)
{
	if (!ModelState.IsValid)
	{
		return View("Index");
	}

In the handler method ModelState.IsValid must be checked as the attribute will add a model error if validation fails. An example:

public IActionResult OnPost()
{
	if (!ModelState.IsValid)
	{
		// Turnstile verification or other verification failed
		return Page();
	}

	// Turnstile verification succeeded...
}

Manual Validation

If you want to manually validate the Turnstile token inject ITurnstileService and IOptions<CloudflareTurnstileOptions>.

Example:

private readonly ITurnstileService _turnstileService;
private readonly IOptions<CloudflareTurnstileOptions> _turnstileOptions;

public ContactModel(ITurnstileService turnstileService, IOptions<CloudflareTurnstileOptions> turnstileOptions)
{
	_turnstileService = turnstileService;
	_turnstileOptions = turnstileOptions;
}

In your page handler, get the turnstile token from the form then call the turnstile service method VerifyAsync to verify the token with CloudFlare. If the returned value is true then the user passed validation.

public async Task<IActionResult> OnPostAsync([FromForm(Name = "cf-turnstile-response")] string turnstileToken)
{
	bool turnstileSuccess = true;
	if (_turnstileOptions.Value.Enabled)
	{
		turnstileSuccess = await _turnstileService.VerifyAsync(turnstileToken);
	}
	// other custom validation

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.1 79 11/17/2024
1.2.0 72 11/16/2024
1.1.1 260 4/18/2024
1.1.0 97 4/18/2024
1.0.3 122 4/17/2024
1.0.2 106 4/16/2024
1.0.1 98 4/16/2024
1.0.0 107 4/16/2024

+ added documentation (Thanks to [rossdonald](https://github.com/rossdonald))