So lösen Sie Cloudflare Turnstile in Node.js und TypeScript

Cloudflare Turnstile tritt in zwei Formen auf, und sie erfordern unterschiedlichen Code. Ein Widget innerhalb eines Formulars ist ein Aufruf mit zwei Argumenten. Eine seitenfüllende Interstitial-Challenge benötigt zwei zusätzliche Werte, die von der Seite ausgelesen werden, und das Token wird nur akzeptiert, wenn Sie den User-Agent zurücksenden, den der Löser verwendet hat. Genau diese letzte Anforderung erzeugt Tokens, die perfekt aussehen und jedes Mal fehlschlagen.
Sie voneinander unterscheiden
| Widget | Challenge-Seite | |
|---|---|---|
| Erscheinungsbild | Ein Kontrollkästchen in einem nutzbaren Formular | Ganzseitiges Interstitial, Seite blockiert |
| Benötigt cData und chlPageData | Nein | Ja |
| Benötigt den zurückgegebenen User-Agent | Nein | Ja |
Unser Live-Turnstile-Demo betreibt die Widget-Variante, was eine nützliche Referenz ist, wenn Sie herausfinden, welche Sie gerade vor sich haben.
Einrichtung
npm install capskip
const { CapSkip } = require('capskip');
const solver = new CapSkip({
host: '127.0.0.1',
port: 8080,
recaptchaTimeout: 300, // seconds, also covers Turnstile
});CapSkip löst lokal, daher muss die Desktop-App laufen, bevor ein Aufruf erfolgreich sein kann.
Widget-Modus
const result = await solver.turnstile( '0x4AAAAAAA...', // the data-sitekey attribute 'https://example.com/login', ); console.log(result.code); // cf-turnstile-response token
Setzen result.code in das cf-turnstile-response Feld ein und übermitteln. Mehr ist nicht nötig.
Challenge-Seiten benötigen zwei weitere Werte
Ein Interstitial trägt anfragebezogenen Status, an den das Token gebunden wird. Zwei Teile davon müssen mit dem Lösen mitgeführt werden:
- cData, übergeben als
data - chlPageData, übergeben als
pagedata
Beide befinden sich in der Challenge-Seite selbst und nicht in einem Formularattribut, sodass die Seite abgerufen werden muss, bevor sie gelöst werden kann. Bei einem Standard-Cloudflare-Interstitial liegen sie im seiteneigenen Challenge-Options-Objekt der Seite’s, direkt neben dem Sitekey. Sie sind für den einmaligen Gebrauch bestimmt und an diesen Seitenaufruf gebunden, also rufen Sie ab und lösen Sie zusammen, statt zu cachen.
const result = await solver.turnstile(sitekey, pageUrl, {
data: cData, // the cData value
pagedata: chlPageData, // the chlPageData value
action: 'managed', // optional, when the page declares one
});
console.log(result.code);
console.log(result.userAgent); // required for the next stepDer User-Agent ist nicht optional
Turnstile bindet das Token an den Browser-Fingerprint, der es erzeugt hat, und der User-Agent ist Teil dieses Fingerprints. CapSkip gibt den zurück, den es verwendet hat, in result.userAgent. Übermitteln Sie den Token stattdessen mit Nodes standardmäßigem fetch-User-Agent, und Cloudflare lehnt einen ansonsten völlig gültigen Token ab.
userAgent wird nur für Turnstile befüllt. Für jeden anderen Captcha-Typ ist es undefined, was genau der Grund ist, warum dies Nutzer zu Fall bringt, die einen funktionierenden reCAPTCHA-Helper wiederverwenden.
const response = await fetch(pageUrl, {
method: 'POST',
headers: {
// Send back the exact user agent the solve was performed with.
'User-Agent': result.userAgent,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
'cf-turnstile-response': result.code,
}),
});Wenn ein Token abgelehnt wird und die cData frisch ist, ist dies fast immer der Grund.
TypeScript
import { CapSkip, SolveResult } from 'capskip';
const solver = new CapSkip({ host: '127.0.0.1', port: 8080 });
const result: SolveResult = await solver.turnstile(sitekey, pageUrl);
// userAgent is optional on the type, because only Turnstile populates it.
if (result.userAgent) {
// safe to forward
}Definitionen werden mit dem Paket ausgeliefert, es gibt also kein @types install. Die optionale Typisierung auf userAgent ist ein nützlicher Hinweis: Der Compiler lässt Sie nicht vergessen, dass andere Captcha-Typen ihn leer lassen.
Proxys und Parallelität
// Solve through the same egress you will submit from.
await solver.turnstile(sitekey, pageUrl, {
data: cData,
pagedata: chlPageData,
proxy: { type: 'HTTPS', uri: 'user:[email protected]:3128' },
});
// Several at once.
const results = await Promise.all(targets.map((t) =>
solver.turnstile(t.sitekey, t.url)));Proxys funktionieren für Turnstile, reCAPTCHA und GeeTest, aber nicht für Bild-Captchas, die die Zielseite nie berühren. Bei Challenge-Seiten benötigt jede Lösung ihre eigenen, frisch abgerufenen cData, holen Sie diese daher innerhalb der gemappten Funktion und nicht vorab im Batch.
Häufig gestellte Fragen
Benötigen Widgets jemals cData?
Nein, und das Übergeben leerer Werte lässt das Lösen eher scheitern, als dass es hilft. Nur ganzseitige Interstitial-Challenges verwenden sie.
Der Token sieht in Ordnung aus, aber die Website lehnt ihn ab.
Fast immer der User Agent. Senden Sie mit result.userAgent anstatt was auch immer Ihr HTTP-Client standardmäßig sendet. Die zweitwahrscheinlichste Ursache ist ein veraltetes cData, das an einen einzigen Seitenaufruf gebunden ist.
Kann ich das mit Puppeteer verwenden?
Ja, und es lässt sich gut kombinieren: Lesen Sie cData aus der geladenen Seite mit page.evaluate, mit diesem SDK lösen, dann denselben User Agent auf der Seite setzen, bevor Sie fortfahren. Unser Node.js-Captcha-Löser Seite behandelt die Automatisierungsseite.
Zusammenfassung
Widgets nehmen einen Sitekey und eine URL. Challenge-Seiten benötigen data und pagedata frisch von der Seite gelesen, und der Token muss übermittelt werden mit result.userAgent. Alles Übrige ist gewöhnliche Promise-Verarbeitung.
Andere Sprachen finden Sie auf der Cloudflare-Turnstile-Löser Seite, Parameterdetails in der API-Dokumentation, und die breitere Node-Oberfläche auf der Node.js-Captcha-Löser Seite. CapSkip ist ein unbegrenzter Captcha-Löser das auf Ihrer eigenen Hardware läuft.
