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.
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.
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",
},
});
},
};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.
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