CodeIgniter 4 Shieldv1.2.x
Challenge & Cookie
Challenge adalah jaring pengaman kedua. Kalau Shield menduga sesuatu mencurigakan tetapi belum cukup yakin untuk memblokir, ia mengarahkan pengunjung ke halaman pembuktian. Kalau berhasil, pengunjung dibolehkan melanjutkan dan ditandai sebagai orang yang sudah terbukti.
Kapan challenge muncul
Section titled “Kapan challenge muncul”Challenge muncul ketika skor request berada di antara thresholdChallenge dan
thresholdBan di app/Config/Shield.php:
public int $thresholdChallenge = 10; // mulai minta challengepublic int $thresholdBan = 20; // mulai kena banJadi request dengan skor 14 mendapat challenge, bukan ban.
Memilih driver
Section titled “Memilih driver”shield.challengeDriver = turnstile| Nilai | Driver | Kapan dipakai |
|---|---|---|
turnstile |
Cloudflare Turnstile | Pilihan kami. Bagus, cepat, dan punya kuota gratis. |
recaptcha / google_recaptcha |
Google reCAPTCHA v2 (checkbox) | Kalau Anda sudah memakai reCAPTCHA di situs. |
null / test / 0 / kosong |
NullTestDriver |
Development dan pengujian otomatis. |
Driver reCAPTCHA memakai widget v2 checkbox (div.g-recaptcha), bukan v3
berbasis skor. Isi SHIELD_RECAPTCHA_SITE_KEY dan
SHIELD_RECAPTCHA_SECRET_KEY; tidak ada opsi action/score v3.
Nama properti config adalah challengeDriver, jadi SHIELD_CHALLENGE tidak
dibaca — pakai shield.challengeDriver (atau shield_challengeDriver).
Nilai yang tidak dikenal tidak melempar error; Shield jatuh ke Turnstile.
Dengan NullTestDriver, verifikasi gagal kecuali token-nya persis test-token.
Gunanya untuk development, bukan untuk produksi.
Menyiapkan Cloudflare Turnstile
Section titled “Menyiapkan Cloudflare Turnstile”1. Buat widget
Section titled “1. Buat widget”Di dashboard Cloudflare, bagian Turnstile, buat widget dengan tipe
Managed. Cloudflare memberi Anda satu site key dan satu secret key.
2. Isi konfigurasi
Section titled “2. Isi konfigurasi”shield.challengeDriver = turnstileSHIELD_TURNSTILE_SITE_KEY=0x4AAAAAAA...SHIELD_TURNSTILE_SECRET_KEY=0x4AAAAAAA...site key aman untuk ditaruh di HTML — memang itu gunanya. secret key
tidak boleh pernah masuk ke repository.
3. Catat domain Anda
Section titled “3. Catat domain Anda”Cloudflare hanya mengirim challenge ke domain yang Anda daftarkan saat membuat
widget. Kalau Anda lupa mendaftarkan localhost atau domain staging, widget
tidak akan tampil saat development.
Verify endpoint
Section titled “Verify endpoint”Saat pengunjung mengirim token, server Anda meneruskannya ke Cloudflare:
POST https://challenges.cloudflare.com/turnstile/v0/siteverifyIsinya: secret, response (token dari widget), dan remoteip (IP
pengunjung, opsional tapi membantu Cloudflare menilai).
Alamat verifikasi bisa diganti kalau Anda mengarahkannya ke server verifikasi
sendiri:
SHIELD_TURNSTILE_VERIFY_URL (Turnstile) atau
SHIELD_RECAPTCHA_VERIFY_URL (reCAPTCHA).
Route challenge
Section titled “Route challenge”Shield mendaftarkan dua route untuk mekanisme ini (dari
Ganadev\Shield\Codeigniter\Config\Routes):
| Method | Route | Nama route | Keterangan |
|---|---|---|---|
GET |
/shield/challenge |
shield.challenge |
Menampilkan widget. |
POST |
/shield/challenge/verify |
shield.challenge.verify |
Memverifikasi token dan memasang cookie. |
Alur di browser
Section titled “Alur di browser”- Request mencurigakan → Shield mengarahkan pengunjung ke
/shield/challenge?redirect=<tujuan>. - Pengunjung menyelesaikan widget, lalu form mengirim token ke
/shield/challenge/verify. - Server memverifikasi token ke Cloudflare/Google.
- Kalau gagal, pengunjung dikembalikan ke halaman challenge dengan
?error=1. - Kalau berhasil, Shield memasang trusted cookie, lalu mengarahkan balik ke halaman tujuan.
Setelah verifikasi berhasil
Section titled “Setelah verifikasi berhasil”Satu verifikasi yang sukses melakukan dua hal sekaligus:
- Mencabut semua efek ban pada IP tersebut — baris ban aktif di database
di-set
released, dan request berikutnya tidak lagi di-redirect ke challenge. - Menerbitkan trusted cookie (
shield_trusted) yang membuat request berikutnya langsung diizinkan tanpa tantangan lagi selamatrustedTtlMinutes.
Trusted cookie
Section titled “Trusted cookie”Setelah lolos, Shield memasang cookie bernama shield_trusted. Atributnya:
| Atribut | Nilai | Untuk apa |
|---|---|---|
HttpOnly |
aktif | JavaScript tidak bisa membacanya. |
Secure |
aktif | Hanya dikirim lewat HTTPS. |
SameSite |
Lax |
Dikirim untuk navigasi tingkat atas saja. |
Atribut Secure di-hardcode true oleh ChallengeController, bukan berasal
dari config. Karena itu challenge produksi wajib berjalan di HTTPS.
Cookie ini yang membuat pengunjung tidak di-challenge berulang kali selama
menjelajah. Masa berlakunya diatur di app/Config/Shield.php:
public int $trustedTtlMinutes = 60;Setel trustedEnabled ke false kalau Anda ingin setiap request yang
mencurigakan selalu di-challenge ulang.
Tujuan setelah challenge
Section titled “Tujuan setelah challenge”Halaman challenge menerima parameter redirect untuk menentukan tujuan
setelah berhasil. Nilainya divalidasi ketat sebelum dipakai:
| Masukan | Hasil |
|---|---|
/produk/123 |
Dipakai. |
https://jahat.example |
Dibuang, dan pengunjung diarahkan ke /. |
//jahat.example |
Dibuang, karena berarti URL protocol-relative. |
/x:y |
Dibuang, karena terbaca seperti scheme. |
\ atau %5c |
Dinormalkan menjadi /, lalu diperiksa ulang. |
Kalau nilai parameter tidak aman, pengunjung diarahkan ke beranda. Ini mencegah attacker memakai challenge sebagai pembuka open redirect.
Menyesuaikan tampilan
Section titled “Menyesuaikan tampilan”Tampilan halaman challenge dan blokir dikendalikan di app/Config/Shield.php:
public string $brandingTitle = 'Toko Online Aman';public string $brandingAccentColor = '#22d3ee';public string $brandingBackgroundColor = '#0b1220';public bool $brandingShowRuleId = false;Bila ingin kendali penuh, salin view bawaan ke aplikasi Anda:
vendor/ganadev/codeigniter4-shield/src/Views/shield/challenge.php→app/Views/shield/challenge.phpvendor/ganadev/codeigniter4-shield/src/Views/shield/blocked.php→app/Views/shield/blocked.php
Lalu arahkan lewat challengeView / blockedView kalau letaknya berbeda dari
itu.
Menguji tanpa pihak ketiga
Section titled “Menguji tanpa pihak ketiga”Dengan shield.challengeDriver=null, Anda bisa menguji alur challenge secara
deterministik:
curl -i "http://localhost:8080/shield/challenge"Verifikasi manual dengan token yang benar:
curl -i -X POST http://localhost:8080/shield/challenge/verify \ -d "shield_challenge_token=test-token" \ -d "redirect=/"Token yang salah akan mengembalikan redirect ke ?error=1.
Kalau challenge tidak muncul
Section titled “Kalau challenge tidak muncul”| Gejala | Penyebab yang paling mungkin |
|---|---|
| Widget tidak tampil sama sekali | site_key kosong, atau domain Anda belum didaftarkan di Cloudflare. |
| Selalu gagal verifikasi | secret_key salah, atau token kedaluwarsa. |
Mengalihkan ke ?error=1 terus-menerus |
Token tidak terkirim, atau driver di null. |
| Pengunjung kena challenge berulang | Trusted cookie tidak tersimpan — periksa HTTPS dan SameSite. |
| Semua orang kena challenge | Skor perilaku terlalu rendah, atau thresholdChallenge terlalu kecil. |
Untuk melihat komponen yang berjalan, gunakan php spark shield:health.
Powered by PT Ganadev Multi Solusi