BuildingBlocks.Security.BotProtection, public form ve giriş akışlarını otomatik botlara karşı korumak için Google reCAPTCHA v3 doğrulaması sağlar. v3 görsel bir challenge sunmaz; her isteğe 0.0–1.0 arası bir skor verir. Validator skoru eşikle, beklenen action ile ve (opsiyonel) hostname ile karşılaştırır; uyuşmazlıkta exception fırlatır.
GoogleRecaptchaValidator implementasyonu Google siteverify API’sine secret + response (token) gönderir ve yanıtı sırayla kontrol eder:
public async Task ValidateAsync(string token, string expectedAction, CancellationToken ct = default){ if (string.IsNullOrWhiteSpace(token)) throw new RecaptchaValidationException("Recaptcha token gerekli."); var content = new FormUrlEncodedContent(new Dictionary<string, string> { ["secret"] = _options.SecretKey, ["response"] = token }); var response = await _httpClient.PostAsync( "https://www.google.com/recaptcha/api/siteverify", content, ct); var result = JsonSerializer.Deserialize<RecaptchaResponse>( await response.Content.ReadAsStringAsync(ct)); if (result is null || !result.Success) throw new RecaptchaValidationException("Recaptcha doğrulaması başarısız oldu."); if (result.Score < _options.ScoreThreshold) throw new RecaptchaValidationException($"Recaptcha puanı çok düşük: {result.Score}"); if (!string.Equals(result.Action, expectedAction, StringComparison.Ordinal)) throw new RecaptchaValidationException("Recaptcha işlemi uyuşmazlığı."); if (_options.ValidateHostname && !_options.AllowedHostnames.Contains(result.Hostname, StringComparer.OrdinalIgnoreCase)) throw new RecaptchaValidationException("Hostname mismatch.");}
public class SubmitContactFormCommandHandler(IRecaptchaValidator recaptcha) : IRequestHandler<SubmitContactFormCommand, Unit>{ public async Task<Unit> Handle(SubmitContactFormCommand request, CancellationToken ct) { // expectedAction frontend'deki grecaptcha.execute({ action: "contact" }) ile eşleşmeli await recaptcha.ValidateAsync(request.RecaptchaToken, expectedAction: "contact", ct); // doğrulama geçtiyse iş mantığı... return Unit.Value; }}
RecaptchaValidationException ProblemDetails katmanında uygun HTTP yanıtına çevrilir.
Skor eşiğini akışa göre ayarlayın: düşük riskli public formlarda 0.5–0.6, login gibi hassas akışlarda 0.7+. action adını her zaman frontend grecaptcha.execute çağrısıyla birebir aynı tutun.