Ana içeriğe atla
Ribaunt, sunucunuz bir gönderimi kabul etmeden önce tarayıcının küçük ama ölçülebilir miktarda hesaplama işi yapmasını sağlayarak formlarınızı ve hassas işlemlerinizi korur. Geleneksel CAPTCHA’ların aksine, bu arka planda sessizce gerçekleşir: sunucunuz şifreleme bulmacası yayınlar, tarayıcı geçerli bir cevap bulana kadar SHA-256 hash’lerini öğütür ve sunucunuz devam etmeden önce kanıtı kontrol eder. Görüntü ızgaraları yok, onay kutusu ritüelleri yok — sadece matematik.

Challenge-response akışı

Her Ribaunt doğrulaması üç adımlı bir döngüyü takip eder.
1

Sunucu challenge tokenlerini yayınlar

Sunucunuz, imzalı JWT tokenlerinden oluşan bir dizi üreten createChallenge() işlevini çağırır. Her token rastgele bir challenge dizesini, zorluk seviyesini (kazanan hash’in kaç baştaki sıfırla başlaması gerektiğini), sona erme zaman damgasını ve tekrar oynatma önleme için benzersiz bir token ID’sini (jti) kodlar. Tokenler RIBAUNT_SECRET ile imzalanır, bu nedenle istemci tarafından sahteciliği yapılamaz veya kurcalanamaz.
import { createChallenge } from 'ribaunt';

// Issue 4 challenges at difficulty 5, valid for 60 seconds
const challenges = createChallenge(5, 4, 60);
2

Tarayıcı challenge'ları çözer

Tarayıcı tokenleri alır ve çözücüyü çalıştırır. Her token için challenge dizesini ve zorluğunu çözer, ardından 0, 1, 2, … gibi aday nonce değerlerini yineleyerek Web Crypto API’sini kullanarak her biri için SHA-256(challenge + nonce) hesaplar. Hash’i gerekli sayıda baştaki sıfırla başlayan bir nonce bulduğu anda, o nonce’u ve hash’i çözüm olarak kaydeder ve bir sonraki tokene geçer.
3

Sunucu çözümleri doğrular

Tarayıcı orijinal tokenlerle birlikte bulduğu çözümleri de gönderir. Sunucunuz verifySolution() işlevini çağırır, bu:
  • JWT imzasını RIBAUNT_SECRET ile doğrular
  • Tokenin süresinin dolmadığını kontrol eder
  • SHA-256(challenge + nonce) değerini yeniden hesaplar ve gerekli baştaki sıfırlarla başladığını onaylar
  • Tokenin daha önce kullanılmadığından emin olmak için jti değerini tekrar oynatma deposuyla karşılaştırır
Yalnızca tüm kontroller geçerse verifySolution() true döndürür.
import { verifySolution } from 'ribaunt';

const valid = await verifySolution(tokens, solutions);

if (!valid) {
  return res.status(400).json({ error: 'Invalid CAPTCHA solution' });
}

Challenge tokenleri

Her challenge tokeni standart, imzalı bir JWT’dir. Çözüldüğünde, yükü şunları içerir:
AlanAçıklama
challengeHer token için yeniden oluşturulan rastgele bir base64 dizesi
difficultySHA-256 hash’inin başlaması gereken baştaki sıfır sayısı
expiresTokenin reddedileceği Unix zaman damgası (saniye)
jtiBu tokeni benzersiz şekilde tanımlayan, tekrar oynatma önleme için kullanılan bir UUID
Tokenler, sunucunuzda ayarladığınız bir ortam değişkeni olan RIBAUNT_SECRET ile imzalanır. Tokenleri üretebilen veya doğrulayabilen tek taraf sunucunuzdur — tarayıcı yalnızca imzalı, opak JWT’yi görür.
RIBAUNT_SECRET değerini asla tarayıcıya açmayın. Next.js’te onu NEXT_PUBLIC_ öneki ile kullanmayın.

Zorluk

difficulty parametresi, kazanan hash’in kaç baştaki sıfıra sahip olması gerektiğini kontrol eder. Her ek sıfır, rastgele bir hash’in nitelik kazanma olasılığını 16 kat azalttığından, her artış, beklenen hash deneme sayısını ve dolayısıyla çözüm süresini yaklaşık olarak iki katına çıkarır.
AyarYaklaşık çözüm süresiÖnerilen kullanım
createChallenge(4, 4, 30)MilisaniyelerHızlı / arka plan kontrolleri
createChallenge(5, 4, 60)~1 saniyeOrta / form gönderimi
createChallenge(5, 8, 120)~2 saniyeYüksek / hassas işlemler
6’nın üzerindeki değerler tarayıcıların donmasına neden olabilir. Doğrulama yapmadan kullanıcıların veya harici girdilerin difficulty, amount veya ttlSeconds değerlerini kontrol etmesine izin vermeyin.

Durumsuz tasarım

Ribaunt, challenge’ları yayınlamak veya doğrulamak için bir veritabanı gerektirmez. Sunucunun bir çözümü doğrulaması için ihtiyaç duyduğu tüm bilgiler — challenge dizesi, gerekli zorluk ve sona erme — doğrudan imzalı JWT tokenine kodlanmıştır. Doğrulama, JWT imzasını kontrol etmeye ve hash’i yeniden hesaplamaya indirgenir; çekirdek kanıt kontrolü için bir veri deposuna gidip dönme gerekmez. Tekrar oynatma koruması, durum gerektiren tek alandır. Bu olmadan, tek bir geçerli çözüm, tokenin TTL penceresi içinde tekrar tekrar gönderilebilir. Ribaunt bunu hafif bir tekrar oynatma deposuyla yönetir:
  • Varsayılan local modunda, süreç içi bir Map, mevcut Node.js süreci içinde kullanılan token ID’lerini takip eder.
  • remote modunda, birden çok süreç veya sunucusuz işlev örneğinin hangi tokenlerin zaten tüketildiğine dair tutarlı bir görüntüyü paylaşması için dağıtık bir depo (Redis veya Valkey gibi) sağlarsınız.
Bu, sunucu altyapınızı basit tutar — oturum tabloları yok, challenge veritabanları yok — ancak yine de şemayı güvenli kılan tekrar oynatma korumasını sağlar.
Tam Redis örneği dahil olmak üzere tekrar oynatma korumasını yapılandırmak hakkında daha fazla ayrıntı için Tekrar Oynatma Koruması sayfasına bakın.

Güvenli bağlam gereksinimi

Tarayıcı çözücüsü, tarayıcıların yalnızca güvenli bağlamlarda açığa çıkardığı Web Crypto API’sini (crypto.subtle) kullanır. Bu, istemci tarafı çözmenin şunlarda çalıştığı anlamına gelir:
  • https:// kökenleri (üretim)
  • http://localhost (yerel geliştirme)
http://192.168.x.x gibi düz LAN adresleri, özellikle mobil tarayıcılarda crypto.subtle’ı açığa çıkarmayabilir. Üretimde uygulamanızı her zaman HTTPS üzerinden sunun.