Composer के साथ PHP में Cloudflare Turnstile कैसे हल करें

Cloudflare Turnstile दो रूपों में दिखता है और उन्हें अलग-अलग PHP की ज़रूरत होती है। किसी form में बैठा widget एक two-argument call है। एक full-page interstitial challenge को पेज से पढ़े गए दो और values की ज़रूरत होती है, और token तभी स्वीकार किया जाता है जब आप सॉल्वर द्वारा उपयोग किया गया user agent वापस भेजें। वह आख़िरी हिस्सा छोड़ दें तो आपको एक ऐसा token मिलता है जो पूरी तरह वैध दिखता है और हर बार अस्वीकृत हो जाता है।
आप किसे देख रहे हैं?
| विजेट | Challenge page | |
|---|---|---|
| स्वरूप | किसी form में एक checkbox जिसे आप अब भी उपयोग कर सकते हैं | फुल-पेज interstitial, सब कुछ ब्लॉक |
| cData और chlPageData चाहिए | नहीं | हां |
| लौटाए गए user agent की ज़रूरत है | नहीं | हां |
हमारा लाइव Turnstile डेमो widget variant चलाता है, जो तुलना के लिए काम आता है।
Setup
# 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 लोकल रूप से हल करता है, इसलिए किसी भी call के सफल होने से पहले desktop app का चालू होना ज़रूरी है।
Widget mode
$result = $solver->turnstile(
'0x4AAAAAAA...', // the data-sitekey attribute
'https://example.com/login'
);
echo $result['code']; // cf-turnstile-response tokenरखें $result['code'] इसमें cf-turnstile-response field और फ़ॉर्म सबमिट करें। widgets के लिए बस यही पूरा फ़्लो है।
Challenge pages को दो और values चाहिए
एक interstitial प्रति-request state रखता है जिससे token बँधा होता है, और इसके दो हिस्सों को हल के साथ यात्रा करनी पड़ती है:
- cData, के रूप में पास किया गया
data - chlPageData, के रूप में पास किया गया
pagedata
ये किसी फॉर्म attribute के बजाय challenge पेज के अंदर रहते हैं, इसलिए हल करने से पहले पेज को fetch करना पड़ता है। एक सामान्य Cloudflare interstitial पर ये पेज के अपने challenge options ऑब्जेक्ट पर sitekey के साथ होते हैं। दोनों single use हैं और उसी पेज लोड से बंधे होते हैं, इसलिए इन्हें कैश करने के बजाय एक साथ fetch और हल करें।
$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 submituser agent यहाँ अनिवार्य है
Turnstile token को उस browser fingerprint से बाँधता है जिसने इसे बनाया, और user agent उस fingerprint का हिस्सा है। CapSkip वह लौटाता है जिसका उसने इसमें इस्तेमाल किया $result['userAgent']. इसके बजाय cURL’s default user agent के साथ सबमिट करें और Cloudflare एक ऐसे token को अस्वीकार कर देता है जो अन्यथा बिल्कुल सही है।
userAgent केवल Turnstile के लिए भरा जाता है। हर दूसरे कैप्चा प्रकार के लिए यह अनुपस्थित होता है, यही वजह है कि यह किसी काम कर रहे reCAPTCHA helper को दोबारा इस्तेमाल करने वाले लोगों को पकड़ लेता है।
$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);अगर कोई token अस्वीकार हो रहा है और cData ताज़ा है, तो लगभग हमेशा यही कारण होता है।
प्रॉक्सी
$result = $solver->turnstile($sitekey, $pageUrl, [
'data' => $cData,
'pagedata' => $chlPageData,
'proxy' => ['type' => 'HTTPS', 'uri' => 'user:[email protected]:3128'],
]);जब challenge geo-sensitive हो, तो उसी egress के ज़रिए हल करें जिससे आप सबमिट करेंगे। प्रॉक्सी Turnstile, reCAPTCHA और GeeTest के लिए काम करते हैं, लेकिन image कैप्चा के लिए नहीं, जो कभी target साइट को छूते ही नहीं।
Errors
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
}सब कुछ के अंतर्गत रहता है CapSkip\Exceptions, Python और Node SDK के विपरीत जो पैकेज रूट से exceptions एक्सपोर्ट करते हैं।
अक्सर पूछे जाने वाले सवाल
क्या widgets को कभी cData की ज़रूरत होती है?
नहीं, और खाली values पास करने से हल में मदद के बजाय विफलता होती है। केवल full-page interstitial challenges ही इनका उपयोग करते हैं।
मेरा token वैध है पर अस्वीकार हो जाता है।
लगभग हमेशा user agent। सेट करें CURLOPT_USERAGENT को $result['userAgent'] cURL’s के डिफ़ॉल्ट को छोड़ने के बजाय। अगला सबसे संभावित कारण एक बासी cData है, जो केवल एक page load तक टिकता है।
क्या इसे किसी web request के अंदर चलना चाहिए?
अधिमानतः नहीं। PHP सिंक्रोनस है और एक Turnstile हल में कुछ सेकंड लगते हैं, इसलिए इसे किसी page render के दौरान करने से एक worker ब्लॉक हो जाता है। इसे किसी queued job या CLI worker में ले जाएँ।
सारांश
विजेट एक sitekey और एक पेज URL लेते हैं। challenge पेज को चाहिए data और pagedata पेज से ताज़ा पढ़ा जाता है, और टोकन को इसके साथ सबमिट करना होता है $result['userAgent']। exceptions यहाँ से import करें CapSkip\Exceptions, और हल को अपने request threads से दूर रखें।
अन्य भाषाएँ इस पर हैं Cloudflare Turnstile सॉल्वर page, parameter विवरण यहाँ हैं API डॉक्युमेंटेशन, और इस पर व्यापक PHP सरफ़ेस PHP कैप्चा सॉल्वर पेज। CapSkip एक है असीमित कैप्चा सॉल्वर आपकी अपनी मशीन पर चल रहा।
