PHP'de Composer ile Cloudflare Turnstile Nasıl Çözülür

solve cloudflare turnstile in php - How to Solve Cloudflare Turnstile in PHP With Composer

Cloudflare Turnstile iki biçimde görünür ve bunlar farklı PHP gerektirir. Bir formda duran widget iki argümanlı bir çağrıdır. Tam sayfa ara doğrulama (interstitial challenge), sayfadan okunan iki değere daha ihtiyaç duyar ve token yalnızca çözücünün kullandığı user agent'ı geri gönderirseniz kabul edilir. Bu son kısmı atlarsanız, tamamen geçerli görünen ama her seferinde reddedilen bir token elde edersiniz.

Hangisine bakıyorsunuz?

WidgetDoğrulama sayfası
GörünümHâlâ kullanabileceğiniz bir formdaki onay kutusuTam sayfa ara sayfa (interstitial), her şey engellenir
cData ve chlPageData gerektirirHayırEvet
Döndürülen user agent'ı gerektirirHayırEvet

Bizim canlı Turnstile demosu widget varyantını çalıştırır, bu da karşılaştırma için kullanışlıdır.

Kurulum

# 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 yerel olarak çözer; bu nedenle herhangi bir çağrı başarılı olmadan önce masaüstü uygulamasının çalışıyor olması gerekir.

Bileşen modu

$result = $solver->turnstile(
    '0x4AAAAAAA...',                 // the data-sitekey attribute
    'https://example.com/login'
);

echo $result['code'];                // cf-turnstile-response token

Koy $result['code'] şunun içine: cf-turnstile-response alanına ve formu gönderin. Widget'lar için tüm akış budur.

Doğrulama sayfaları iki değer daha gerektirir

Bir ara sayfa (interstitial), token'ın bağlı olduğu istek başına durum bilgisi taşır ve bunun iki parçasının çözümle birlikte gitmesi gerekir:

  • cData, şu olarak geçirilir: data
  • chlPageData, şu olarak geçirilir: pagedata

Bunlar bir form özniteliğinde değil, challenge sayfasının içinde bulunur; bu yüzden çözülmeden önce sayfanın getirilmesi gerekir. Standart bir Cloudflare ara sayfasında (interstitial) bunlar, sitekey ile birlikte sayfanın kendi challenge seçenekleri nesnesinde yer alır. Her ikisi de tek kullanımlıktır ve o sayfa yüklemesine bağlıdır, bu yüzden bunları önbelleğe almak yerine birlikte getirip çözün.

$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 submit

user agent burada zorunludur

Turnstile, token'ı onu üreten tarayıcı parmak izine bağlar ve user agent bu parmak izinin bir parçasıdır. CapSkip, kullandığı user agent'ı şurada döndürür: $result['userAgent']. Bunun yerine cURL’ün varsayılan user agent'ı ile gönderin ve Cloudflare, aksi takdirde gayet iyi olan bir token'ı reddeder.

userAgent yalnızca Turnstile için doldurulur. Diğer her CAPTCHA türü için mevcut değildir; işte bu yüzden çalışan bir reCAPTCHA yardımcısını yeniden kullanan insanları şaşırtır.

$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);

Bir token reddediliyorsa ve cData tazeyse, neden neredeyse her zaman budur.

Proxy'ler

$result = $solver->turnstile($sitekey, $pageUrl, [
    'data' => $cData,
    'pagedata' => $chlPageData,
    'proxy' => ['type' => 'HTTPS', 'uri' => 'user:[email protected]:3128'],
]);

Challenge coğrafyaya duyarlı olduğunda, gönderim yapacağınız çıkış noktasının aynısı üzerinden çözün. Proxy'ler Turnstile, reCAPTCHA ve GeeTest için çalışır ancak hedef siteye asla dokunmayan görüntü CAPTCHA'ları için çalışmaz.

Hatalar

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
}

Her şey şunun altında yer alır: CapSkip\Exceptions, istisnaları paket kökünden dışa aktaran Python ve Node SDK'larının aksine.

Sık sorulan sorular

Widget'ların hiç cData'ya ihtiyacı olur mu?

Hayır, ve boş değerler geçmek yardımcı olmak yerine çözümü başarısız kılar. Bunları yalnızca tam sayfa ara doğrulamalar kullanır.

Token'ım geçerli ama reddediliyor.

Neredeyse her zaman user agent. Ayarlayın CURLOPT_USERAGENT şuraya $result['userAgent'] cURL’ün varsayılanını bırakmak yerine. Bir sonraki en olası neden, yalnızca bir sayfa yüklemesi kadar dayanan eskimiş bir cData'dır.

Bu bir web isteği içinde mi çalışmalı?

Tercihen hayır. PHP eşzamanlıdır (synchronous) ve bir Turnstile çözümü birkaç saniye sürer, dolayısıyla bunu bir sayfa oluşturma sırasında yapmak bir işçiyi (worker) engeller. Bunu kuyruğa alınmış bir işe veya bir CLI işçisine taşıyın.

Özet

Widget'lar bir sitekey ve bir sayfa URL'si alır. Challenge sayfaları şuna ihtiyaç duyar: data ve pagedata sayfadan taze okunur ve token'ın şununla gönderilmesi gerekir $result['userAgent']. Exception'ları şuradan içe aktarın: CapSkip\Exceptions, ve çözümleri istek iş parçacıklarınızın dışında tutun.

Diğer diller şuradadır: Cloudflare Turnstile çözücü sayfası, parametre ayrıntıları şuradadır: API dokümantasyonu, ve şuradaki daha geniş PHP yüzeyi PHP CAPTCHA çözücü sayfası. CapSkip bir sınırsız captcha çözücü kendi makinenizde çalışan.