So lösen Sie Cloudflare Turnstile in PHP mit Composer

Cloudflare Turnstile erscheint in zwei Formen, und sie erfordern unterschiedlichen PHP-Code. Ein Widget in einem Formular ist ein Aufruf mit zwei Argumenten. Eine ganzseitige Interstitial-Challenge benötigt zwei weitere Werte, die aus der Seite ausgelesen werden, und der Token wird nur akzeptiert, wenn Sie den User Agent zurücksenden, den der Löser verwendet hat. Lassen Sie diesen letzten Teil aus, erhalten Sie einen Token, der völlig gültig aussieht und jedes Mal abgelehnt wird.
Welches sehen Sie sich an?
| Widget | Challenge-Seite | |
|---|---|---|
| Erscheinungsbild | Eine Checkbox in einem Formular, das Sie weiter nutzen können | Seitenfüllendes Interstitial, alles blockiert |
| Benötigt cData und chlPageData | Nein | Ja |
| Benötigt den zurückgegebenen User-Agent | Nein | Ja |
Unser Live-Turnstile-Demo führt die Widget-Variante aus, was für den Vergleich praktisch ist.
Einrichtung
# PHP 8.0+, with the curl and json extensions. composer require capskip/capskip
use CapSkip\CapSkip;
$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
$result = $solver->turnstile(
'0x4AAAAAAA...', // the data-sitekey attribute
'https://example.com/login'
);
echo $result['code']; // cf-turnstile-response tokenSetzen $result['code'] in das cf-turnstile-response -Feld und senden Sie das Formular ab. Das ist der gesamte Ablauf für Widgets.
Challenge-Seiten benötigen zwei weitere Werte
Ein Interstitial trägt Zustand pro Anfrage, an den der Token gebunden ist, und zwei Teile davon müssen mit der Lösung mitreisen:
- cData, übergeben als
data - chlPageData, übergeben als
pagedata
Sie befinden sich innerhalb der Challenge-Seite und nicht in einem Formularattribut, daher muss die Seite abgerufen werden, bevor sie gelöst werden kann. Auf einer Standard-Cloudflare-Zwischenseite liegen sie im seiteneigenen Challenge-Options-Objekt neben dem sitekey. Beide sind nur einmal verwendbar und an diesen Seitenaufruf gebunden – rufen Sie sie also gemeinsam ab und lösen Sie sie, anstatt sie zwischenzuspeichern.
$result = $solver->turnstile($sitekey, $pageUrl, [
'data' => $cData, // the cData value from the page
'pagedata' => $chlPageData, // the chlPageData value
'action' => 'managed', // optional, when the page declares one
]);
echo $result['code'];
echo $result['userAgent']; // needed for the submitDer User-Agent ist hier zwingend erforderlich
Turnstile bindet den Token an den Browser-Fingerprint, der ihn erzeugt hat, und der User-Agent ist Teil dieses Fingerprints. CapSkip gibt den zurück, den es verwendet hat in $result['userAgent']. Senden Sie stattdessen mit dem Standard-User-Agent von cURL, und Cloudflare weist einen Token ab, der ansonsten völlig einwandfrei ist.
userAgent wird nur für Turnstile befüllt. Er fehlt bei jedem anderen Captcha-Typ, weshalb dies Nutzer erwischt, die einen funktionierenden reCAPTCHA-Helfer wiederverwenden.
$ch = curl_init($pageUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
// Send back the exact user agent the solve was performed with.
CURLOPT_USERAGENT => $result['userAgent'],
CURLOPT_POSTFIELDS => http_build_query([
'cf-turnstile-response' => $result['code'],
]),
]);
$response = curl_exec($ch);
curl_close($ch);Wenn ein Token abgelehnt wird und das cData frisch ist, ist dies fast immer die Ursache.
Proxys
$result = $solver->turnstile($sitekey, $pageUrl, [
'data' => $cData,
'pagedata' => $chlPageData,
'proxy' => ['type' => 'HTTPS', 'uri' => 'user:[email protected]:3128'],
]);Lösen Sie über denselben Egress, von dem aus Sie absenden werden, wenn die Challenge geo-sensitiv ist. Proxys funktionieren für Turnstile, reCAPTCHA und GeeTest, aber nicht für Bild-Captchas, die die Zielwebsite nie berühren.
Fehler
use CapSkip\Exceptions\ApiException;
use CapSkip\Exceptions\NetworkException;
use CapSkip\Exceptions\TimeoutException;
try {
$result = $solver->turnstile($sitekey, $pageUrl, $options);
} catch (NetworkException $e) {
// CapSkip is not running on the configured port
} catch (ApiException $e) {
// often a stale cData, since it is bound to one page load
} catch (TimeoutException $e) {
// exceeded recaptchaTimeout
}Alles befindet sich unter CapSkip\Exceptions, anders als die SDKs für Python und Node, die Exceptions aus dem Paket-Root exportieren.
Häufig gestellte Fragen
Benötigen Widgets jemals cData?
Nein, und das Übergeben leerer Werte lässt die Lösung fehlschlagen, statt zu helfen. Nur ganzseitige Interstitial-Challenges verwenden sie.
Mein Token ist gültig, wird aber abgelehnt.
Fast immer der User-Agent. Setzen Sie CURLOPT_USERAGENT zu $result['userAgent'] anstatt cURLs Standard zu belassen. Die nächstwahrscheinlichste Ursache ist ein veraltetes cData, das nur einen einzigen Seitenaufruf überlebt.
Sollte dies innerhalb einer Web-Anfrage laufen?
Vorzugsweise nicht. PHP ist synchron, und eine Turnstile-Lösung dauert einige Sekunden, sodass das Ausführen während eines Seiten-Renderings einen Worker blockiert. Verlagern Sie es in einen in die Warteschlange gestellten Job oder einen CLI-Worker.
Zusammenfassung
Widgets nehmen einen sitekey und eine Seiten-URL. Challenge-Seiten benötigen data und pagedata frisch von der Seite gelesen, und der Token muss gesendet werden mit $result['userAgent']. Importieren Sie Ausnahmen aus CapSkip\Exceptions, und halten Sie Lösungen von Ihren Anfrage-Threads fern.
Andere Sprachen finden Sie auf der Cloudflare-Turnstile-Löser Seite, Parameterdetails in der API-Dokumentation, und die breitere PHP-Oberfläche auf der PHP-Captcha-Löser Seite. CapSkip ist ein unbegrenzter Captcha-Löser läuft auf Ihrem eigenen Rechner.
