OnCourse.Turnstile
1.0.0
dotnet add package OnCourse.Turnstile --version 1.0.0
NuGet\Install-Package OnCourse.Turnstile -Version 1.0.0
<PackageReference Include="OnCourse.Turnstile" Version="1.0.0" />
<PackageVersion Include="OnCourse.Turnstile" Version="1.0.0" />
<PackageReference Include="OnCourse.Turnstile" />
paket add OnCourse.Turnstile --version 1.0.0
#r "nuget: OnCourse.Turnstile, 1.0.0"
#:package OnCourse.Turnstile@1.0.0
#addin nuget:?package=OnCourse.Turnstile&version=1.0.0
#tool nuget:?package=OnCourse.Turnstile&version=1.0.0
<div align="center"> <h1>OnCourse.Turnstile</h1> <img src="preview.gif" width="300" /> <p>ASP.NET Core middleware for integrating <a href="https://developers.cloudflare.com/turnstile">Cloudflare Turnstile CAPTCHA</a>.</p>
</div>
Requirements
This package requires a secret key and a site key provided by Cloudflare Turnstile. You can obtain these keys by signing up for a free account on their website.
Installing the NuGet Package
You can install the package from NuGet or with one of the following commands:
# Using the NuGet Package Manager Console
PM> Install-Package OnCourse.Turnstile
# Using the .NET CLI
dotnet add package OnCourse.Turnstile
Usage
Register the Turnstile service in your Program.cs
:
// Pass in configuration options from appsettings.json
builder.Services.AddTurnstile(builder.Configuration.GetSection("Turnstile"));
// Or configure directly in code
builder.Services.AddTurnstile(options =>
{
options.SiteKey = "your-site-key";
options.SecretKey = "your-secret-key";
});
You can then add the Turnstile element to your DOM using the following Razor syntax:
@Html.Turnstile()
In the action you are submitting to, you can validate the Turnstile response like this:
[ValidateTurnstile]
[HttpPost]
public IActionResult SubmitForm(MyModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Process the form submission
// ...
return RedirectToAction("Success");
}
Turnstile TagHelper
To use the tag helper, add the following to your _ViewImports.cshtml
:
@addTagHelper *, OnCourse.Turnstile
Then, you can use the Turnstile tag helper in your views:
<form method="post">
<turnstile></turnstile>
<button type="submit">Submit</button>
</form>
TagHelper Attributes
You can customize the Turnstile tag helper with the following attributes (Cloudflare documentation):
site-key
: The site key for your Turnstile account.action
: A custom value that can be used to differentiate widgets under the same site key in analytics.cdata
: A custom payload that can be used to attach customer data and returned upon validation.callback
: A JavaScript function that will be called when the Turnstile challenge is completed successfully.error-callback
: A JavaScript function that will be called when there is an error with the Turnstile challenge.execution
: Controls when to obtain the token of the widget. Options arerender
(default) or onexecute
.expired-callback
: A JavaScript function that will be called when the Turnstile challenge expires.before-interactive-callback
: A JavaScript function that will be called before the challenge enters interactive mode.after-interactive-callback
: A JavaScript function that will be called when the challenge has left interactive mode.unsupported-callback
: A JavaScript function that will be called when the Turnstile widget is not supported in the current browser/client.theme
: The theme of the Turnstile widget. Options arelight
,dark
, andauto
(default).language
: Language to display, must be eitherauto
(default) or a valid language code.timeout-callback
: A JavaScript function that will be called when the Turnstile challenge was not solved within a given time.size
: The size of the Turnstile widget. Options arenormal
(default),compact
, andflexible
.retry
: Controls whether the Turnstile widget should retry automatically if it fails to obtain a token. Options areauto
(default) ornever
.retry-interval
: The interval in milliseconds to wait before retrying to obtain a token ifretry
is set toauto
. Default is8000
ms, maximum value is900000
ms (15 minutes).refresh-expired
: Automatically refreshes the token when it expires. Options areauto
(default),manual
ornever
.refresh-timeout
: Controls whether the widget should automatically refresh after a timeout. Options areauto
(default),manual
ornever
.appearance
: Appearance controls when the widget is visible. Options arealways
(default),execute
, orinteraction-only
.feedback-enabled
: Allows Cloudflare to collect feedback on the widget's performance. Options aretrue
(default) orfalse
.
Examples
You can find two example projects in the Samples
folder of this repository. You will need to set up your own Cloudflare Turnstile keys in the appsettings.json
files of these projects:
OnCourse.Turnstile.Mvc
: A simple ASP.NET Core MVC application demonstrating basic usage.OnCourse.Turnstile.RazorPages
: A simple ASP.NET Core Razor Pages application demonstrating basic usage.
Dummy Sitekeys and Secretkeys
The following sitekeys and secret keys are available for testing (docs). These dummy sitekeys will produce the XXXX.DUMMY.TOKEN.XXXX
response token. The dummy secret keys will only accept that response token and production secret keys will not accept it.
Sitekey | Description | Visibility | |
---|---|---|---|
1x00000000000000000000AA | Always passes | visible | |
2x00000000000000000000AB | Always blocks | visible | |
1x00000000000000000000BB | Always passes | invisible | |
2x00000000000000000000BB | Always blocks | invisible | |
3x00000000000000000000FF | Forces an interactive challenge | visible |
| Secret key | Description | 1x0000000000000000000000000000000AA | Always passes | 2x0000000000000000000000000000000AA | Always fails | 3x0000000000000000000000000000000AA | Yields a "token already spent" error
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | 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. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Options (>= 8.0.0)
-
net9.0
- Microsoft.Extensions.Options (>= 8.0.0)
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.0.0 | 365 | 7/25/2025 |