Hoe Cloudflare te omzeilen
In dit artikel leer je hoe je de Cloudflare-pagina "Verifying you are human" kunt omzeilen met NodeJS en browserautomatisering via Playwright.

Laten we eerst kort begrijpen hoe Cloudflare werkt. Zonder Cloudflare hosten websitebeheerders hun pagina’s op een server met een openbaar IP-adres. De domeinnamen verwijzen naar dat IP-adres en jouw browser maakt rechtstreeks verbinding met hun server.
Wanneer ze Cloudflare gebruiken, delegeren ze het DNS-beheer aan Cloudflare, dat de domeinnamen begint op te lossen naar zijn eigen IP-adressen. Op die IP-adressen draaien speciale proxyservers die inkomende HTTP- en HTTPS-verzoeken filteren.
Nieuwe bezoekers zien de welbekende pagina met de tekst: "Verifying you are human. This may take a few seconds.". Tijdens deze verificatie kan het zijn dat je een captcha moet oplossen. Voorheen gebruikten ze reCAPTCHA, maar tegenwoordig gebruiken ze hun eigen Turnstile-captcha.
Zodra de captcha is opgelost, ontvangt de browser een uniek token in een cookie met de naam cf_clearance. Jouw browser gebruikt dit token om pagina’s van de website via de Cloudflare-proxy op te vragen. Als dit token verloopt of Cloudflare intern beslist dat het zich gedraagt als een bot, wordt het ongeldig gemaakt en zie je opnieuw de verificatiepagina.
Onze methode helpt je om dit token te verkrijgen via een geautomatiseerde browsersessie. Merk op dat deze methode het echte IP-adres van de website niet onthult — die informatie is alleen bekend bij Cloudflare en de sitebeheerders. En dat is maar goed ook!
Zo doe je dat met NodeJS en Playwright:
// Install packages
// npx install playwright @antiadmin/anticaptchaofficial
import { chromium } from "playwright";
import ac from "@antiadmin/anticaptchaofficial";
// Specify the target website address
const websiteBehindCloudFlare = 'https://yourwebsite.com';
// Set your Anti-Captcha API key here:
ac.setAPIKey('API_KEY_HERE');
ac.setSoftId(0);
let browser = null;
let page = null;
(async () => {
// Opening the browser
try {
console.log('Opening browser ..');
browser = await chromium.launch({ headless: false });
console.log('Creating new page ..');
page = await browser.newPage();
} catch (e) {
console.log("Could not open browser: "+e.toString());
return;
}
let params = null;
try {
// Doing several attempts to inject our code
while (!params) {
console.log('Navigating to the page')
await page.goto(websiteBehindCloudFlare);
console.log('Injecting our proxy code to replace window.turnstile');
await page.evaluate(() => {
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === "render") {
return function (a, b) {
const p = {
websiteURL: window.location.href,
websiteKey: b.sitekey,
action: b.action,
cData: b.cData,
chlPageData: b.chlPageData,
userAgent: navigator.userAgent,
};
// saving params in window.params
window.params = p;
// assigning callback to a variable
window.cfCallback = b.callback
// calling original render function
return target.render.apply(this, arguments);
};
}
return target[prop];
},
});
});
console.log('Getting params');
params = await page.evaluate(() => {
return new Promise((resolve) => {
setTimeout(() => resolve(window.params || null), 5000);
});
});
if (!params) {
console.log('Retrying..');
await delay(3000);
}
}
console.log("Extracted Turnstile Params:", params);
console.log('Solving Turnstile captcha with Anti-Captcha')
const token = await ac.solveTurnstileProxyless(websiteBehindCloudFlare, params.websiteKey, params.action, params.cData, params.chlPageData);
// Running Cloudflare's callback function we previously assigned to window.cfCallback
await page.evaluate((token) => {
window.cfCallback(token)
}, token);
console.log('Waiting for redirects to finish')
await delay(5000);
// Get all cookies for current page
const cookies = await page.context().cookies();
// Find cf_clearance
const cf_clearance = cookies.filter(c => c.name === 'cf_clearance');
// Output cookies
console.log('Cookies:', cookies);
console.log('cf_clearance:', cf_clearance);
} catch (e) {
console.error('Could not inject proxy code:', e);
}
// close browser when needed
// await browser.close();
})();
function delay(time) {
return new Promise(function(resolve) {
setTimeout(resolve, time)
});
}
Wat onze code doet:
1. Open een browservenster en navigeer naar de Cloudflare-verificatiepagina.
2. Vervang de renderfunctie van Turnstile door onze proxyfunctie, waarin we de initialisatieparameters en de callback voor voltooide captcha opvangen.
3. Verstuur de initialisatieparameters naar de Anti-Captcha API. Menselijke werknemers lossen de captcha voor je op en geven een token terug.
4. Roep de eerder opgeslagen callbackfunctie aan met het Turnstile-token als parameter.
5. Cloudflare verifieert het token intern, stelt de -cookie in je browser in en herlaadt de pagina.
6. Met die cf_clearance haalt de browser de inhoud van de website op via de Cloudflare-proxy.