C# में Cloudflare Turnstile Challenge Pages कैसे हल करें

Cloudflare Turnstile दो रूपों में आता है, और प्रत्येक के लिए C# कोड अलग होता है। किसी form में एम्बेड किया गया widget केवल एक sitekey और एक URL माँगता है। एक full-page interstitial challenge को पेज से निकाले गए दो अतिरिक्त values की ज़रूरत होती है, और इसे तभी स्वीकार किया जाएगा जब आप सॉल्वर द्वारा उपयोग किया गया user agent वापस भेजें। वह आख़िरी हिस्सा चूक गए तो आपको एक ऐसा token मिलता है जो एकदम सही दिखता है और हर बार validation में विफल हो जाता है।
यह गाइड दोनों को कवर करता है, काम करने वाले .NET code के साथ।
Widget या challenge page?
कोई भी कोड लिखने से पहले पता लगाएँ कि आप किसे देख रहे हैं।
| Widget mode | Challenge page | |
|---|---|---|
| आप जो देखते हैं | किसी फ़ॉर्म के अंदर एक checkbox जिससे आप अब भी इंटरैक्ट कर सकते हैं | एक फुल-पेज interstitial, आमतौर पर “Checking your browser” |
| page का बाक़ी हिस्सा | सामान्य रूप से लोड होता है | challenge हल होने तक ब्लॉक |
चाहिए data / pagedata | नहीं | हां |
| लौटाए गए user agent की ज़रूरत है | नहीं | हां |
अगर आप अनिश्चित हैं, तो हमारा live Turnstile demo पेज widget variant चलाता है, ताकि आप इसकी तुलना उससे कर सकें जिसे आप असल में हिट कर रहे हैं।
Setup
CapSkip आपके अपने मशीन पर चलता है, इसलिए इनमें से कुछ भी काम करने से पहले शुरू करने के लिए एक लोकल सेवा है। NuGet से SDK install करें:
# .NET Standard 2.0, so this works on .NET Framework 4.6.1+, # .NET Core 2.0+, and .NET 6 through 9. dotnet add package CapSkip
फिर client को CapSkip app में दिखाए गए port पर लगाएं:
using CapSkip;
var solver = new CapSkipClient(
apiKey: "capskip", // any string when key validation is off
host: "127.0.0.1",
port: 8080,
recaptchaTimeout: 300); // seconds, also covers Turnstile and GeeTestWidget mode, आसान मामला
दो आर्गुमेंट और आपका काम पूरा:
var result = await solver.TurnstileAsync(
"0x4AAAAAAA...", // sitekey from the data-sitekey attribute
"https://example.com/login");
Console.WriteLine(result.Code); // cf-turnstile-response tokenDrop result.Code इसमें cf-turnstile-response field और form सबमिट करें। और कुछ नहीं करना है।
Challenge pages को दो और values चाहिए
एक interstitial challenge प्रति-request state रखता है जिससे token बंधा होता है। इसके दो हिस्से आपकी हल request के साथ जाने चाहिए:
- cData, के रूप में पास किया गया
data - chlPageData, के रूप में पास किया गया
pagedata
दोनों किसी form attribute के बजाय challenge page में ही embedded होते हैं, इसलिए हल करने से पहले आपको page पढ़ना पड़ता है। किसी standard Cloudflare interstitial पर वे page के अपने challenge options object पर, sitekey के साथ, उपलब्ध होते हैं।
वे single-use भी हैं और उस विशिष्ट पेज लोड से बंधे होते हैं। उन्हें प्राप्त करें, तुरंत हल करें, और प्रयासों के बीच उन्हें cache न करें।
using System.Collections.Generic;
using CapSkip;
var result = await solver.TurnstileAsync(
sitekey,
pageUrl,
new Dictionary<string, object?>
{
["data"] = cData, // the cData value from the page
["pagedata"] = chlPageData, // the chlPageData value
["action"] = "managed", // optional, when the page declares one
});
Console.WriteLine(result.Code);
Console.WriteLine(result.UserAgent); // you are going to need thisवह हिस्सा जो हर कोई चूक जाता है: user agent
Turnstile टोकन को उस ब्राउज़र फिंगरप्रिंट से बाँधता है जिसने उसे बनाया, और user agent उसका हिस्सा है। CapSkip उसे लौटाता है जिसका उसने उपयोग किया result.UserAgent। अगर आप फिर token को किसी से सबमिट करते हैं HttpClient अपना खुद का डिफ़ॉल्ट user agent भेजते हुए, मान मेल नहीं खाते और Cloudflare एक ऐसे token को अस्वीकार कर देता है जो अन्यथा पूरी तरह वैध है।
UserAgent केवल Turnstile के लिए भरा जाता है। हर दूसरे कैप्चा प्रकार के लिए यह null होता है, यही वजह है कि जब लोग किसी काम कर रहे reCAPTCHA helper को दोबारा इस्तेमाल करते हैं तो यह उन्हें उलझा देता है।
using System.Net.Http;
using CapSkip;
var result = await solver.TurnstileAsync(sitekey, pageUrl, options);
using var http = new HttpClient();
// Send back the exact user agent the solve was performed with.
http.DefaultRequestHeaders.UserAgent.ParseAdd(result.UserAgent);
var form = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("cf-turnstile-response", result.Code),
});
var response = await http.PostAsync(pageUrl, form);अगर आपका token अस्वीकार किया जा रहा है और आपने expired होने की संभावना ख़ारिज कर दी है cData, लगभग हमेशा यही कारण होता है।
विफलताओं को ठीक से संभालना
हर SDK exception इससे व्युत्पन्न होता है CapSkipError, ताकि आप उस एक टाइप को पकड़ सकें या हर एक को अलग-अलग संभाल सकें। एक .NET-विशिष्ट जाल है जिसे जानना ज़रूरी है।
using System;
using CapSkip;
try
{
var result = await solver.TurnstileAsync(sitekey, pageUrl, options);
}
catch (CapSkip.ValidationException) { /* bad parameters */ }
catch (NetworkException) { /* CapSkip is not running */ }
catch (ApiException) { /* API returned an error code */ }
catch (CapSkip.TimeoutException) { /* exceeded recaptchaTimeout */ }
catch (CapSkipError) { /* anything else from the SDK */ }TimeoutException और ValidationException दोनों में मौजूद हैं System और CapSkip. दोनों namespaces import होने पर, एक unqualified catch (TimeoutException) इससे हल होता है System एक और चुपचाप कभी फ़ायर नहीं होता। इन्हें ऊपर बताए अनुसार क्वालिफ़ाई करें, या बस catch करें CapSkipError और इसका निरीक्षण करें।
एक साथ कई हल करना
हर मेथड एक लौटाती है Task, इसलिए सामान्य .NET concurrency लागू होती है:
var results = await Task.WhenAll(
solver.TurnstileAsync(sitekeyA, "https://a.example.com"),
solver.TurnstileAsync(sitekeyB, "https://b.example.com"));
foreach (var r in results)
{
Console.WriteLine(r.Code);
}SDK यह भी export करता है AsyncCapSkip, लेकिन .NET में यह केवल का एक alias है CapSkipClient। यह इसलिए मौजूद है ताकि Python SDK से पोर्ट किया गया कोड कम्पाइल होता रहे। इस पर स्विच करने से आपको कुछ हासिल नहीं होता, क्योंकि .NET I/O पहले से ही asynchronous है।
एक प्रॉक्सी के ज़रिए रूटिंग
अगर challenge geo-sensitive है, तो उसी network path से हल करें जहां से आप सबमिट करेंगे:
var result = await solver.TurnstileAsync(sitekey, pageUrl,
new Dictionary<string, object?>
{
["data"] = cData,
["pagedata"] = chlPageData,
["proxy"] = new Proxy("HTTPS", "user:[email protected]:3128"),
});प्रॉक्सी Turnstile, reCAPTCHA और GeeTest के लिए समर्थित हैं। वे इमेज कैप्चा के लिए समर्थित नहीं हैं, जो इमेज बाइट्स से हल किए जाते हैं और कभी टारगेट साइट को छूते ही नहीं।
अक्सर पूछे जाने वाले सवाल
क्या मुझे हमेशा cData और chlPageData चाहिए?
नहीं। सिर्फ़ फ़ुल-पेज interstitial challenges के लिए। किसी फ़ॉर्म के अंदर बैठे Turnstile widget को sitekey और page URL के अलावा कुछ नहीं चाहिए, और किसी widget पर खाली मान पास करना हल में मदद करने के बजाय उसे विफल कर देगा।
मेरा token valid है लेकिन साइट फिर भी इसे रिजेक्ट करती है। क्यों?
लगभग हमेशा user agent। Turnstile टोकन को उस फिंगरप्रिंट से बाँधता है जिसने उसे बनाया, इसलिए आपको उस वैल्यू का उपयोग करके सबमिट करना होता है जो result.UserAgent. दूसरा सबसे आम कारण एक बासी है cData, जो एक ही पेज लोड से बंधा होता है।
क्या यह .NET Framework पर काम करता है?
हाँ। पैकेज .NET Standard 2.0 को टारगेट करता है, इसलिए यह .NET Framework 4.6.1 और नए, .NET Core 2.0+, और हर आधुनिक .NET रिलीज़ पर चलता है। सिंक्रोनस कोड से आप कॉल कर सकते हैं .GetAwaiter().GetResult(), हालाँकि सही तरीके से await करना बेहतर है।
एक Turnstile हल में कितना समय लगना चाहिए?
आमतौर पर कुछ सेकंड। client आंतरिक रूप से poll करता है, 250ms से शुरू होकर पीछे हटते हुए pollingInterval, और इस पर हार मान लेता है recaptchaTimeout जो डिफ़ॉल्ट रूप से 300 सेकंड होता है। अगर आप लगातार उस सीमा तक पहुँच रहे हैं, तो timeout बढ़ाने के बजाय जाँचें कि CapSkip सेवा वास्तव में चल रही है।
सारांश
Widget Turnstile एक दो-आर्गुमेंट वाली कॉल है। चैलेंज पेजों को चाहिए data और pagedata पेज से ताज़ा पढ़ा गया, और token को उसके साथ लौटाए गए user agent के साथ सबमिट करना होता है। Catch CapSkipError namespace टकराव से जूझने के बजाय, और जब challenge geo-sensitive हो तो एक प्रॉक्सी इस्तेमाल करें।
.NET के लिए पूरा मेथड सरफेस यहाँ है C# कैप्चा सॉल्वर पेज, parameter संदर्भ यहाँ है API डॉक्युमेंटेशन, और Turnstile समर्थन अन्य languages को कवर करता है। CapSkip खुद एक असीमित कैप्चा सॉल्वर जो लोकल रूप से चलता है, इसलिए ऊपर दी गई किसी चीज़ की प्रति हल लागत नहीं है।
