You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A minimal, no-drama, friction-less **C#****HTTP** verification client for **Cloudflare**'s [**Turnstile** API](https://developers.cloudflare.com/turnstile/).
9
9
10
10
The problem with current **Turnstile** libraries in **.NET** is that all of them take a hard dependency on the underlying web framework like **ASP.NET WebForms**, **ASP.NET MVC 5**, **ASP.NET Core**, or **ASP.NET Razor Pages**.
You'll need a **Cloudflare** account. You can sign up [here](https://www.cloudflare.com/)! After you sign up and setup your domain, you'll have two important pieces of information:
42
+
You'll need a **Cloudflare** account. Get started by following the directions [here](https://developers.cloudflare.com/turnstile/get-started/)! After you sign up and you're signed into the dashboard; you'll need two important pieces of information:
43
43
1. Your `site` key
44
44
2. Your `secret` key
45
45
@@ -52,202 +52,91 @@ This library supports all widget types:
52
52
## Turnstile
53
53
### Client-side Setup
54
54
55
-
Be sure to checkout [this video that describes how Turnstile v3 works](https://www.youtube.com/watch?v=tbvxFW4UJdU) before implementing.
55
+
Be sure to [read the documentation](https://developers.cloudflare.com/turnstile/) before implementing.
56
56
57
-
Then, on every page of your website, add the following JavaScript:
57
+
Then, to protect an **HTML** form submission on your website, add the following:
Every page should call `gTurnstile.execute` with some unique **action**`TAG`. [Read more about actions in the official docs here](https://developers.google.com/Turnstile/docs/v3#actions).
74
-
75
-
When it is time to validate an **HTTP**`POST` you'll need transfer the captcha `token` in the browser to a hidden HTML form field as shown below:
You'll need to execute `ExecuteTurnstile_OnSome_ButtonAction()` function the moment the user decides to submit your form. Otherwise, if you run `gTurnstile.*` code during page load, the token being copied to the hidden field can expire after a few minutes. This means, if the user takes a long time filling out a form, the token copied at page load can expire and your server will validate an expired token by the time the form is submitted resulting in a failed captcha verification.
102
-
103
-
Therefore, you should execute the `ExecuteTurnstile_OnSome_ButtonAction()` function on some `onclick=` event to get a fresh token before the form is submitted.
104
-
105
-
Also, keep in mind, `gTurnstile.execute()` returns a **JavaScript Promise**. You won't have a valid token in your `<form>` until the line `$("#captcha").val(token);` above executes. So you'll need to postpone the form submission until `$("#captcha").val(token);` is actually executed. Then, *and only then,* you can continue submitting the HTML form to have it validated on your server with a valid token.
106
-
107
-
### Verifying the POST Server-side
108
-
When the `POST` is received on the server:
109
-
1. Get the client's IP address. If you're using **CloudFlare**, be sure to use the [`CF-Connecting-IP` header value][0].
110
-
2. Extract the `#captcha` value (client token) in the hidden **HTML** form field.
111
-
3. Use the `TurnstileService` to verify the client's **Turnstile** is valid.
112
-
113
-
```csharp
114
-
//1. Get the client IP address in your chosen web framework
115
-
stringclientIp=GetClientIpAddress();
116
-
stringtoken=null;
117
-
stringsecret="your_secret_key";
118
-
119
-
//2. Extract the `#captcha` field from the hidden HTML form in your chosen web framework
<details><summary>GetClientIpAddress() in ASP.NET WebForms</summary>
154
-
<p>
155
-
156
-
**Note:** If your site is behind CloudFlare, be sure you're suing the [`CF-Connecting-IP` header value][0] instead.
157
-
158
-
```csharp
159
-
publicstringGetClientIpAddress(){
160
-
returnthis.Request.UserHostAddress;
161
-
}
162
-
```
163
-
164
-
</p>
165
-
</details>
166
-
167
-
You'll want to make sure the action name you choose for the request is legitimate. The `result.Score` is the probably of a human. So, you'll want to make sure you have a `result.Score > 0.5`; anything less is probably a bot.
168
-
169
-
## Turnstile v2 (I'm not a robot)
170
-
### Client-side Setup
171
-
Add the following `<div class="g-Turnstile">` and `<script>` tags to your **HTML** form:
When the user visits the **HTML** form, a hidden form field `cf-turnstile-response` will be added to the **HTML** form above. The `cf-turnstile-response` represents a token of the captcha challenge result and will need to be verified server-side when the **HTML** form is posted to your server.
186
73
187
74
### Verifying the POST Server-side
188
-
When the `POST` is received on the server:
189
-
1. Get the client's IP address. If you're using **CloudFlare**, be sure to use the [`CF-Connecting-IP` header value][0].
190
-
2. Extract the `g-Turnstile-response`(Client Response) **HTML** form field.
191
-
3. Use the `TurnstileService` to verify the client's **Turnstile** is valid.
75
+
When the **HTML** form `POST` is received on the server:
76
+
1. Get the client's IP address. If you're using **Cloudflare**, be sure to use the [`CF-Connecting-IP` header value][0].
77
+
2. Extract the hidden form field `cf-turnstile-response`from the browser's form POST submission.
78
+
3. Use the `TurnstileService` to verify that the client's **Turnstile**`cf-turnstile-response` challenge is valid.
192
79
193
-
The following example shows how to verify the captcha during an **HTTP**`POST` back in **ASP.NET Core: Razor Pages**.
80
+
The following example shows how to verify the captcha during an **HTTP**form `POST` back in **ASP.NET Core: Razor Pages**.
194
81
195
82
```csharp
196
83
//1. Get the client IP address in your chosen web framework
197
-
stringclientIp=GetClientIpAddress();
198
-
stringcaptchaResponse=null;
199
84
stringsecret="your_secret_key";
85
+
stringclientIp=GetClientIpAddress();
86
+
stringbrowserChallengeToken=null;
200
87
201
-
//2. Extract the `g-Turnstile-response` field from the HTML form in your chosen web framework
this.ModelState.AddModelError("captcha", "The Turnstile is not valid.");
100
+
this.ModelState.AddModelError("captcha", "The Cloudflare challenge is not valid.");
213
101
returnnewBadRequestResult();
214
102
}
215
103
else{
216
104
//continue processing, everything is okay!
217
105
}
218
106
```
219
107
220
-
<details><summary>GetClientIpAddress() in ASP.NET Core</summary>
108
+
**Notes:**
109
+
* The `TurnstileService.VerifyAsync` supports an optional idempotency parameter; you can read more about that [here](https://developers.cloudflare.com/turnstile/get-started/server-side-validation/#accepted-parameters).
110
+
* The `clientIp` is technically optional but providing the client's IP address prevents abuses by ensuring that the current HTTP request is the one that received the token.
111
+
112
+
<details><summary><b>GetClientIpAddress() in ASP.NET Core</b></summary>
221
113
<p>
222
114
223
-
**Note:** If your site is behind CloudFlare, be sure you're suing the [`CF-Connecting-IP` header value][0] instead.
115
+
**Note:** If your site is behind Cloudflare, be sure you're using the [`CF-Connecting-IP` header value][0] instead.
0 commit comments