Google reCaptcha servisininde "Ben Robot Değilim" yazısının görünmediği türü, Invisible - reCaptcha olarak adlandırılır.
En sık bilinen reCaptcha'da kullanıcı ben robot değilim yazısına sürekli tıklayarak işkence haline gelebilir ya da bazı sayfalarda tasarımsal olarak kötü bir görüntüye yol açabilir.
Invisible versiyonunda, reCaptchayı gizleyerek kullanıcı deneyimini olumlu hale getirecek ve güvenlik önleminden ödün vermeyeceğiz.
Örneğimize geçmeden önce, Invisible Recaptcha Api Geliştirici dokümantasyonunu incelemenizi öneriririm, örneğimizde belli noktalarda bu linkten destek aldım.
https://developers.google.com/recaptcha/docs/invisible
Konu ile ilgili .NET platformunda ve ajax post ile kısıtlı örnekler olduğu için bir örnek uygulama ile daha kolay anlaşılması amaçlanmaktadır. Proje Github Linki için tıklayınız.
Örneğimizde;
NET Core Web uygulaması üzerinde basit bir kullanıcı giriş sayfası oluşturulup, bu formu ajax post ile submit edeceğiz. Post işlemi öncesi client-side doğrulamayı jQuery Validator kütüphanesi ile yapacağız ve zorunlu alanların doğrulanması sağlandıktan sonra ajax post ile önce recaptcha response değerini arka planda doğrulanmasını göreceğiz.
Önce ASP.NET Core Web App seçerek web sitemizi oluşturacağız.
Web projemizin ismi: GoogleInvisibleRecaptcha.Web olarak oluşturdum.
Ek bilgilere .Target Framework kısmında .NET 5.0 olarak verdiğimize emin olalım. Enable Razor runtime compilation seçmemizin sebebi.
Bu bilgilerden sonra web projemiz oluşturulmuştur. Recaptcha için iş katmanı ile model katmanını oluşturmamız gerekmektedir. Add New Project dedikten sonra, .Net Core Class Library seçip isimlerini ReCaptcha.Business ve ReCaptcha.Models katmanlarını sırası ile oluşturabiliriz. Target Framework kısmında .NET 5.0 olarak verdiğimize emin olalım.
ReCaptcha.Business: reCaptcha doğrulama işleminin yapıldığı projedir. Projedeki ReCaptchaManager sınıfımızda doğrulama işlemi yapacak metot bulunmaktadır.
ReCaptcha.Models: reCaptcha doğrulaması sonuç nesnesinin döndüren ReCaptchaResponse sınıfı bulunmaktadır. Bu sınıfta Success ve Message propertylerini web tarafında kullanacağız.
GoogleInVisibleRecaptcha sınıfı ise appsettings.json dosyasındaki GoogleInVisibleRecaptcha kısmındaki SiteKey ve SecretKey değerlerini tutan propertylerini içeren sınıftır. Options Pattern tekniği kullanılmıştır. Options Pattern ile ilgili yazıma ulaşmak için tıklayınız.
Oluşturduğumuz iki proje aşağıdaki gibi görünmektedir.
public class GoogleInVisibleRecaptcha | |
{ | |
public string SiteKey { get; set; } | |
public string SecretKey { get; set; } | |
} |
ReCaptchaManager sınıfında bulunan CheckInvisibleCaptchaValid metodu ile secretKey ve formdan gelen response değeri ile captcha doğrulaması yapılır ve ReCaptchaResponse türünde sonuç nesnesi döndürür. secretKey değeri değişken olduğu için web projemizdeki appsettings.json dosyasından okunması sağlanmıştır.
public class ReCaptchaManager | |
{ | |
public static ReCaptchaResponse CheckInvisibleCaptchaValid(string secretKey, string responseFromForm) | |
{ | |
var client = new System.Net.WebClient(); | |
var reply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secretKey, responseFromForm)); | |
return JsonConvert.DeserializeObject<ReCaptchaResponse>(reply); | |
} | |
} |
public class ReCaptchaResponse | |
{ | |
public bool Success { get; set; } | |
public string Message { get; set; } | |
} |
{ | |
"GoogleInVisibleRecaptcha": { | |
"SiteKey": "YourSiteKey", | |
"SecretKey": "YourSecretKey" | |
}, | |
"AllowedHosts": "*" | |
} |
Google reCaptcha site kaydı ve Invisible reCaptcha keyi elde etmek için aşağıdaki linki kullanıp ekran görüntüsündeki alanları seçmelisiniz.
https://www.google.com/recaptcha/admin/create
Recaptcha modüllerini tamamladıktan sonra web tarafında formumuzu ve script metotlarımızı oluşturalım.
<div id="login"> | |
<h3 class="text-center text-white pt-5">Görünmez Captcha Test</h3> | |
<div class="container"> | |
<div id="login-row" class="row justify-content-center align-items-center"> | |
<div id="login-column" class="col-md-6"> | |
<div id="login-box" class="col-md-12"> | |
<form id="login-form" class="form"> | |
<h3 class="text-center text-info">Giriş Yap</h3> | |
<div class="form-group"> | |
<label for="username" class="text-info">Kullanıcı Adı:</label><br> | |
<input type="text" name="username" id="username" class="form-control"> | |
</div> | |
<div class="form-group"> | |
<label for="password" class="text-info">Şifre:</label><br> | |
<input type="password" name="password" id="password" class="form-control"> | |
</div> | |
<div class="g-recaptcha" | |
data-sitekey="@ViewBag.SiteKey" | |
data-callback="formSubmitCallBack" | |
data-size="invisible"></div> | |
<div class="form-group"> | |
<input type="submit" onclick="validate();" class="btn btn-info btn-md" value="Giriş Yap"> | |
</div> | |
</form> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> |
function validate() { | |
try { | |
$("#login-form").validate({ | |
rules: { | |
username: { required: true }, | |
password: { required: true } | |
}, | |
errorClass: "errorForm", | |
messages: { | |
username: { required: "Lütfen kullanıcı adınızı giriniz!" }, | |
password: { required: "Lütfen şifrenizi giriniz!" } | |
}, | |
submitHandler: function (form) { | |
if (grecaptcha.getResponse()) { | |
var response = grecaptcha.getResponse(); | |
$.ajax({ | |
url: "/Recaptcha/CheckInvisibleCaptchaValid", | |
type: "POST", | |
data: { "g-recaptcha-response": response}, | |
contentType: 'application/x-www-form-urlencoded; charset=UTF-8', | |
success: function (response) { | |
if (response && response.success) { | |
alert("Captcha doğrulandı, form submit edilebilir."); | |
} | |
else { | |
console.error("Captcha hatası!") | |
grecaptcha.reset(); | |
grecaptcha.execute(); | |
} | |
}, | |
error: function (err) { | |
grecaptcha.reset(); | |
} | |
}); | |
} else { | |
grecaptcha.reset(); | |
grecaptcha.execute(); | |
} | |
return false; | |
} | |
}); | |
} catch (e) { | |
console.error(e); | |
} | |
} |
public class RecaptchaController : Controller | |
{ | |
private readonly GoogleInVisibleRecaptcha _invisibleRecaptchaOptions; | |
public RecaptchaController(IOptions<GoogleInVisibleRecaptcha> invisibleRecaptchaOptions) | |
{ | |
_invisibleRecaptchaOptions = invisibleRecaptchaOptions.Value; | |
} | |
[HttpPost] | |
public JsonResult CheckInvisibleCaptchaValid() | |
{ | |
var response = HttpContext.Request.Form["g-recaptcha-response"]; | |
var secretKey = _invisibleRecaptchaOptions.SecretKey; | |
var captchaResponse = ReCaptchaManager.CheckInvisibleCaptchaValid(secretKey, response); | |
return Json(captchaResponse); | |
} | |
} |
public class HomeController : Controller | |
{ | |
private readonly GoogleInVisibleRecaptcha _invisibleRecaptchaOptions; | |
public HomeController(IOptions<GoogleInVisibleRecaptcha> invisibleRecaptchaOptions) | |
{ | |
_invisibleRecaptchaOptions = invisibleRecaptchaOptions.Value; | |
} | |
public IActionResult Login() | |
{ | |
ViewBag.SiteKey = _invisibleRecaptchaOptions.SiteKey; | |
return View(); | |
} | |
[HttpPost] | |
public IActionResult Login(Login loginModel) | |
{ | |
//Kullanıcı giriş kontrolleri ve validasyon işlemleri yapılabilir. | |
return View(); | |
} | |
} |
Login metodunda ViewBag.SiteKey nesnesi ile SiteKeyi Login viewinde eklemiş olduk.Post metodunda ise siz istediğiniz validasyon ve iş kurallarını ekleyebilirsiniz.
Yorumlar
Yorum Gönder