Cara Memecahkan Cloudflare Turnstile di PHP Dengan Composer

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

Cloudflare Turnstile muncul dalam dua bentuk dan keduanya memerlukan PHP yang berbeda. Widget yang berada di dalam formulir adalah panggilan dua argumen. Tantangan interstisial satu halaman penuh memerlukan dua nilai tambahan yang dibaca dari halaman, dan tokennya hanya diterima jika Anda mengirimkan kembali user agent yang digunakan pemecah. Lewatkan bagian terakhir itu dan Anda mendapat token yang terlihat sepenuhnya valid tetapi selalu ditolak.

Yang mana yang sedang Anda lihat?

WidgetHalaman challenge
TampilanKotak centang di formulir yang masih bisa Anda gunakanInterstisial satu halaman penuh, semuanya terblokir
Membutuhkan cData dan chlPageDataTidakYa
Membutuhkan user agent yang dikembalikanTidakYa

Kami demo Turnstile langsung menjalankan varian widget, yang praktis untuk perbandingan.

Penyiapan

# 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 memecahkan secara lokal, jadi aplikasi desktop harus berjalan sebelum panggilan apa pun berhasil.

Mode widget

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

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

Letakkan $result['code'] ke dalam cf-turnstile-response tersebut dan kirim formulirnya. Itulah keseluruhan alur untuk widget.

Halaman challenge membutuhkan dua nilai tambahan

Interstitial membawa state per permintaan yang mengikat token, dan dua bagian darinya harus ikut dikirim bersama pemecahan:

  • cData, diteruskan sebagai data
  • chlPageData, diteruskan sebagai pagedata

Keduanya berada di dalam halaman tantangan, bukan di atribut formulir, sehingga halamannya harus diambil sebelum dapat dipecahkan. Pada interstisial Cloudflare standar, keduanya berada pada objek opsi tantangan milik halaman itu sendiri bersama sitekey. Keduanya sekali pakai dan terikat pada pemuatan halaman tersebut, jadi ambil dan pecahkan sekaligus alih-alih menyimpannya di cache.

$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 wajib di sini

Turnstile mengikat token ke fingerprint browser yang menghasilkannya, dan user agent adalah bagian dari fingerprint itu. CapSkip mengembalikan nilai yang dipakainya di $result['userAgent']. Kirim dengan user agent bawaan cURL dan Cloudflare akan menolak token yang sebenarnya sepenuhnya baik.

userAgent hanya terisi untuk Turnstile. Nilainya tidak ada untuk setiap tipe CAPTCHA lain, itulah sebabnya hal ini menjebak orang yang memakai ulang helper reCAPTCHA yang sudah bekerja.

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

Jika sebuah token ditolak dan cData-nya masih baru, ini hampir selalu penyebabnya.

Proxy

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

Pecahkan melalui jalur keluar yang sama dengan yang akan Anda pakai untuk mengirim ketika tantangannya sensitif terhadap lokasi. Proxy berfungsi untuk Turnstile, reCAPTCHA, dan GeeTest, tetapi tidak untuk CAPTCHA gambar, yang tidak pernah menyentuh situs target.

Kesalahan

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
}

Semuanya berada di bawah CapSkip\Exceptions, tidak seperti SDK Python dan Node yang mengekspor exception dari root paket.

Pertanyaan yang sering diajukan

Apakah widget pernah membutuhkan cData?

Tidak, dan mengirim nilai kosong justru membuat pemecahan gagal alih-alih membantu. Hanya tantangan interstitial satu halaman penuh yang menggunakannya.

Token saya valid tetapi ditolak.

Hampir selalu user agent. Atur CURLOPT_USERAGENT ke $result['userAgent'] alih-alih membiarkan nilai bawaan cURL. Penyebab paling mungkin berikutnya adalah cData yang basi, yang hanya bertahan satu kali muat halaman.

Haruskah ini berjalan di dalam permintaan web?

Sebaiknya tidak. PHP bersifat sinkron dan pemecahan Turnstile memakan beberapa detik, jadi melakukannya saat render halaman akan memblokir sebuah worker. Pindahkan ke job antrean atau worker CLI.

Ringkasan

Widget memerlukan sitekey dan URL halaman. Halaman challenge memerlukan data dan pagedata dibaca baru dari halaman, dan token harus dikirim bersama $result['userAgent']. Impor exception dari CapSkip\Exceptions, dan jauhkan pemecahan dari thread permintaan Anda.

Bahasa lain ada di Pemecah Cloudflare Turnstile halaman, detail parameter di dokumentasi API, dan cakupan PHP yang lebih luas ada di halaman pemecah CAPTCHA PHP halaman. CapSkip adalah pemecah captcha tanpa batas berjalan di komputer Anda sendiri.