← Cloudflare Turnstile / turnstile / tutorials
Conditionally enforce Turnstile
This tutorial explains how to conditionally enforce Turnstile based on the incoming request, such as a pre-shared secret in a header or a specific IP address.
Overview
You may have setups such as automation that cannot load or run the Turnstile challenge. Using HTMLRewriter, this tutorial will demonstrate how to conditionally handle the client-side widget and Siteverify API when specific criteria are met.
Implementation
This tutorial will modify the existing Turnstile demo ↗ to conditionally remove the existing script and widget container elements.
export default {
async fetch(request) {
// ...
+ if (request.headers.get("x-bypass-turnstile") === "VerySecretValue") {
+ class RemoveHandler {
+ element(element) {
+ element.remove();
+ }
+ }
+
+ return new HTMLRewriter()
+ // Remove the script tag
+ .on(
+ 'script[src="https://challenges.cloudflare.com/turnstile/v0/api.js"]',
+ new RemoveHandler(),
+ )
+ // Remove the container used in implicit rendering
+ .on(
+ '.cf-turnstile',
+ new RemoveHandler(),
+ )
+ // Remove the container used in explicit rendering
+ .on(
+ '#myWidget',
+ new RemoveHandler(),
+ )
+ .transform(body);
+ }
return new Response(body, {
headers: {
"Content-Type": "text/html",
},
});
},
};Server-side integration
We will exit early in our validation if the same logic we used to remove the client-side elements is present.
async function handlePost(request) {
+ if (request.headers.get("x-bypass-turnstile") === "VerySecretValue") {
+ return new Response('Turnstile not enforced on this request')
+ }
// Proceed with validation as normal!
const body = await request.formData();
// Turnstile injects a token in "cf-turnstile-response".
const token = body.get('cf-turnstile-response');
const ip = request.headers.get('CF-Connecting-IP');
// ...
}With these changes, Turnstile will not be enforced on requests with the header x-bypass-turnstile: VerySecretValue present.
Demonstration
After running npm run dev in the project folder, you can test the changes by running the following command:
curl -X POST http://localhost:8787/handler -H "x-bypass-turnstile: VerySecretValue"Turnstile not enforced on this request