Laravel Shieldv1.2.x
Challenge
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 thresholds.challenge
dan thresholds.ban:
$thresholds = [ 'challenge' => 10, // mulai muncul challenge 'ban' => 20, // mulai kena ban 'strong_ban' => 30, // ban lebih lama];Jadi request dengan skor 14 mendapat challenge, bukan ban. Ini yang membuat
mode: challenge jauh lebih aman daripada mode: enforce untuk situs yang
masih mendapat traffic tinggi.
Memilih driver
Section titled “Memilih driver”SHIELD_CHALLENGE=turnstile| Nilai | Driver | Kapan dipakai |
|---|---|---|
turnstile |
Cloudflare Turnstile | Pilihan kami. Bagus, cepat, dan punya kuota gratis. |
recaptcha |
Google reCAPTCHA v3 | Kalau Anda sudah memakai reCAPTCHA di situs. |
google_recaptcha |
Sama dengan recaptcha |
Alias, untuk memudahkan. |
null |
Tanpa pihak ketiga | Development dan pengujian otomatis. |
null membuat verifikasi selalu 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_CHALLENGE=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).
Kalau Anda memakai proxy di depan Cloudflare, remoteip yang terkirim adalah
IP proxy — bukan IP asli pengunjung. Cloudflare akan tetap memverifikasi, tapi
penilaiannya sedikit kurang optimal. Isi
bots.verification.ip_ranges dan konfigurasi proxy untuk mengatasi ini.
Alamat di atas bisa diganti lewat challenge.turnstile.verify_url kalau Anda
mengarahkannya ke server verifikasi sendiri.
Alur di browser
Section titled “Alur di browser”Shield membuat dua route untuk mekanisme ini:
| Method | Route | Nama route | Keterangan |
|---|---|---|---|
GET |
/shield/challenge |
shield.challenge |
Menampilkan widget. |
POST |
/shield/challenge/verify |
shield.challenge.verify |
Memverifikasi token. Dibatasi 10 permintaan per menit. |
- Request mencurigakan → Shield membalas
401dengan headerX-Shield-Challenge: 1dan body JSON yang memuatchallenge_url. - Klien membuka
challenge_url. Halaman dirender denganCache-Control: no-storesupaya tidak pernah tersimpan cache. - Pengunjung menyelesaikan widget, lalu form mengirim token ke
/shield/challenge/verify. - Server memverifikasi token ke Cloudflare.
- Kalau gagal, pengunjung dikembalikan ke halaman challenge dengan
?error=1. - Kalau berhasil, Shield menandai IP sebagai “sudah lolos”, memasang trusted cookie, lalu mengarahkan balik ke halaman tujuan.
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. |
Cookie ini yang membuat pengunjung tidak di-challenge berulang kali selama mengjelajah. Masa berlakunya diatur oleh:
SHIELD_TRUSTED_TTL_MINUTES=60Setel trusted.enabled 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”SHIELD_BRANDING_TITLE=Toko Online AmanSHIELD_BRANDING_ACCENT=#22d3eeSHIELD_BRANDING_BG=#0b1220Kalau Anda ingin kendali penuh atas HTML, publish view bawaan lalu ubah:
php artisan vendor:publish --provider="Ganadev\Shield\Laravel\ShieldServiceProvider" --tag=shield-viewsLalu arahkan views.challenge ke view Anda sendiri:
SHIELD_VIEW_CHALLENGE=my-challengeVariabel yang tersedia di view: siteKey, testToken, csrfToken,
redirect, error, dan branding.
Menguji tanpa pihak ketiga
Section titled “Menguji tanpa pihak ketiga”Dengan SHIELD_CHALLENGE=null, Anda bisa menguji alur challenge secara
deterministik:
curl -i "http://localhost:8000/shield/challenge"Verifikasi manual dengan token yang benar:
curl -i -X POST http://localhost:8000/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”Periksa satu per satu:
| 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 |
remoteip tidak dipercaya, atau cookie di-domain lain. |
| Pengunjung kena challenge berulang | Trusted cookie tidak tersimpan — periksa HTTPS dan SameSite. |
| Semua orang kena challenge | Skor behavior terlalu rendah, atau thresholds.challenge terlalu kecil. |
Untuk melihat komponen yang berjalan, gunakan php artisan shield:health.
Powered by PT Ganadev Multi Solusi