ASP .NET Google reCAPTCHA s3 Kullanımı

ASP .NET Google reCAPTCHA s3 Kullanımı


Size bu sitede kullanmış olduğum kaynak kodlarımı açıyorum, hacklemeye çalışacağınızı hisseder gibiyim. Ama özgüvenim tam ve kolay gelsin :)

<form asp-action="Login" asp-controller="Login" method="post">
	<input asp-for="Email">
	<input asp-for="Password" type="password">
	<button type="submit">Giriş</button>
</form>

Şöyle temiz mi temiz bir formumuz olsun. Hadi buna güvenlik ekleyelim. Hemen sizi şuraya alalım.

  • Kendinize hesap oluşturunuz. reCAPTCHA
  • Burada + butonuna tıklayıp key alacağız.
  • Etiket alanına isim giriniz.
  • Tür olarak reCAPTCHA s3'ü seçiniz.
  • Alan adınızı giriniz.
  • Test için ekstradan alan adlarına localhost ekleyiniz.
  • Gönder'e basınız.

Bu işlemden sonra reCAPTCHA s3 SİTE ANAHTARI ve SİTE GİZLİ ANAHTARI'nı alacaksınız ve apiye erişebileceksiniz. (Yazımızda bunlar için key ve secret olarak hitap edeceğiz.)

Google sayfasıyla işimiz bitti. Hadi kodlayalım...

CLIENT SIDE Yukarıda verdiğimiz güvensiz formumuzu yeniden yapılandıralım. (jquery kullanmayan arkadaşlar functionı tekrar yapılandırabileceğini düşünüyorum, bilmeyenler için yorumlara ekleme yapılacaktır.)

<!DOCTYPE html>
<html lang="tr">
<body>
<form asp-action="Login" asp-controller="Login" method="post" id="pc-form" asp-antiforgery="true">
	<p>@ViewBag.Error</p>
	<input asp-for="Email">
	<input asp-for="Password" type="password">
	<button class="g-recaptcha"
		data-sitekey="GoogleRecaptchaKey"
		data-callback="pcOnSubmit"
    data-action="submit">Giriş</button>
</form>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js"></script>
<script>
    function pcOnSubmit() {
        let pcForm = $('#pc-form');
        pcForm.submit();
    }
</script>
</body>
</html>

İnternette birden fazla çözüm göreceksiniz. Bunlardan çoğunun S3 kullanımı yanlış. Ayrıntıda olan kısım Google reCAPTCHA kullanıcının güvenilir olup olmadığını anlamak için kullanıcıya bir token verir ve o tokenın güvenilir olup olmadığını anlamak için sizde serverınızda kontrol edersiniz. Bu tokenların 2 dakika süresi vardır ve netteki kaynakların bir kısmında bu göz ardı edilmiştir. Bu yazınızda butona her bastığınızda yeni token aldığınız için böyle bir derdiniz olmayacaktır. Ayrıca butonun submit type nı kaldırdığımıza dikkat ediniz.

BACKEND Kullanıcı butona bastığı an Request datasıyla birlikte servera google reCAPTCHA token bilgisi de gidecektir. Hadi gelen tokenı google soralım ve bu kullanıcı güvenilir mi öğrenelim.

  1. reCAPTCHA Response Modelimiz
    public class ReCaptchaTokenResponse
    {
        [JsonProperty("success")] 
        public bool Success { get; set; }

        [JsonProperty("score")] 
        public decimal Score { get; set; }

        [JsonProperty("action")]
        public string Action { get; set; }

        [JsonProperty("error-codes")] 
        public List<string> ErrorCodes { get; set; }
    }
  1. Controller
public class LoginController : BaseController
{
    private readonly IHttpClientFactory _httpClientFactory;

    public LoginController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public IActionResult Index()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(WebLoginReq model)
    {
        if (!ModelState.IsValid)
            return View("~/Views/Login/Index.cshtml");
        try
        {
            string token = Request.Form["g-recaptcha-response"];
            using var client = _httpClientFactory.CreateClient();
            var response = await client.GetStringAsync($"https://www.google.com/recaptcha/api/siteverify"
                                                       + $"?secret={GoogleRecaptchaSecret}"
                                                       + $"&response={token}");
            var tokenResponse = JsonConvert.DeserializeObject<ReCaptchaTokenResponse>(response);
            if (!tokenResponse.Success)
                throw new Exception("ROBOT MUSUN");

            // database login işlemleri. Kullanıcı var mı yok mu kontrol ediniz. Login işlemlerinizi yapınız.

            return RedirectToAction("Index", "Home");
        }
        catch (Exception ex)
        {
            ViewBag.Error = ex.Message;
            return View("~/Views/Login/Index.cshtml");
        }
    }
}

Happy Coding!

An error has occurred. This application may no longer respond until reloaded. Reload 🗙