ASP NET Core Google reCAPTCHA v3 Eklemek

Bu yazımızda , size Google reCAPTCHA v3ASP.NET Core projemizdeki bir forma nasıl ekleyeceğimizi göstereceğim.

reCAPTCHA nedir? gibi sorularımız için: link

İlk önce kodlarımızı yazmadan, Google reCAPTCHA v3 key'lerimizi oluşturalım.

Oluşturmak için : link

Google ReCaptcha V3 Create

V3 versiyonu seçiyoruz. "reCAPTCHA v3, herhangi bir kullanıcı etkileşimi olmaksızın bir etkileşimin yasal olup olmadığını doğrulamanıza olanak tanır." API yardımıyla bize bir score döndürür, dönen score ile kontroller yapmamıza yardımcı olur.

Daha fazla detay için : link

Gerekli alanları doldurduktan sonra "gönder" butonuna tıklıyoruz. Ve Google reCAPTCHA v3 apimizin secret key ve site key'lerini oluşturmuş oluyoruz.

Bu keyleri ASP.NET Core projemizde, appsettings.json dosyamıza ekleyeceğiz.

ASP.NET Core Google Recaptcha

Şimdi key'lerimizi oluşturduğumuza göre artık ASP.NET Core projemize geçebiliriz.

İlk önce appsettings.json dosyamıza, secret key ve site key'lerini tanımlıyoruz.

appsetting.json dosyamız;

"Google": {
    "RecaptchaV3SecretKey": "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe", //google test keys
    "RecaptchaV3SiteKey": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI", //google test keys
    "RecaptchaMinScore": 0.5
}

Google reCAPTHCHA api için bir response model tanımlıyoruz.

public class RecaptchaResponse
{
    [JsonProperty("success")]
    public bool Success { get; set; }
    [JsonProperty("error-codes")]
    public IEnumerable<string> ErrorCodes { get; set; }
    [JsonProperty("challenge_ts")]
    public DateTime ChallengeTs { get; set; }
    [JsonProperty("hostname")]
    public string Hostname { get; set; }
    [JsonProperty("score")]
    public decimal Score { get; set; }
}

Validator'ımız için bir interface ve tanımladığımız interface'i implement edeceğimiz class'ımızı tanımlıyoruz.

Interfacemiz;

public interface IRecaptchaValidator
{
    bool IsRecaptchaValid(string token);
}

Classımız;

public class RecaptchaValidator : IRecaptchaValidator
{
    private const string GoogleRecaptchaAddress = "https://www.google.com/recaptcha/api/siteverify";

    public readonly IConfiguration Configuration;

    public RecaptchaValidator(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public bool IsRecaptchaValid(string token)
    {
        using var client = new HttpClient();
        var response = client.GetStringAsync($@"{GoogleRecaptchaAddress}?secret={Configuration["Google:RecaptchaV3SecretKey"]}&response={token}").Result;
        var recaptchaResponse = JsonConvert.DeserializeObject<RecaptchaResponse>(response);

        if (!recaptchaResponse.Success || recaptchaResponse.Score < Convert.ToDecimal(Configuration["Google:RecaptchaMinScore"]))
        {
            return false;
        }
        return true;
    }

}

ASP.NET Core Recaptcha v3

Yukarıda IsRecaptchaValid metotunda recaptcha api'ına istek atıyoruz gelen sonucu responseModelimize deserialize ettikten sonra kontrol ediyoruz eğer Success false ise ya da gelen score AppSetting'de tanımlamış olduğumuz score'dan küçükse false döndürüyoruz değilse true döndürerek isteğin geçerli olduğunu kabul ediyoruz.

Startup.cs'imize IRecaptchaValidator ekliyoruz.

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<IRecaptchaValidator, RecaptchaValidator>();
}

Şimdi Index.cshtml sayfamızda basit bir form tanımlıyoruz.

<h3>Subscribe Newsletter</h3>
<form asp-page-handler="SubscribeNewsletter" method="post" id="newsletter-form">
    <div class="form-group">
        <label>Email Address</label>
        <input type="email" name="email" value="" class="form-control" />
    </div>
    <div class="form-group text-right">
        <input type="submit" value="Submit" />
    </div>
</form>

Index.cshtml'in recaptcha için script kodlarını yazıyoruz.

@section Scripts {
    <script src="https://www.google.com/recaptcha/api.js?render=@Configuration["Google:RecaptchaV3SiteKey"]"></script>
    <script>
        grecaptcha.ready(function () {
            grecaptcha.execute("@Configuration["Google:RecaptchaV3SiteKey"]", { action: "newsletter" })
                .then(function (token) {
                    //double check
                    $('#newsletter-form').prepend('<input type="hidden" name="token" value="' + token + '">');
                    $.getJSON("@Url.Page("Index","RecaptchaVerify")&token=" + token, function (data) {
                        $('#newsletter-form').find("input[type=submit]").prop("disabled", !data);
                    });
                });
        });
    </script>
}

Burdaki kodlarımızı özetlersek sayfamız açıldığında grecaptcha'ten bir token dönüyor bu gelen token'ı formumuzun içerisine hidden input olarak ekliyoruz ve sonra back-end'de tanımlamış olduğumuz RecaptchaVerify handler'ında valid olup olmadığını kontrol ediyoruz eğer valid değilse submit butonunu disabled et diyoruz.(Formumuz submit edilememesi için).

Sayfamızın back-end kodlarına geçelim;

Index.cshtml.cs

public class IndexModel : PageModel
{
    public readonly IRecaptchaValidator RecaptchaValidator;
    public IndexModel(IRecaptchaValidator recaptchaValidator)
    {
        RecaptchaValidator = recaptchaValidator;
    }
    public void OnGet()
    {

    }

    public IActionResult OnPostSubscribeNewsletter(string email, string token)
    {
        if (!RecaptchaValidator.IsRecaptchaValid(token))
        {
            //return error message or something
            return BadRequest();
        }
        //todo add the email to newsletter
        return Page();
    }

    public JsonResult OnGetRecaptchaVerify(string token)
    {
        return new JsonResult(RecaptchaValidator.IsRecaptchaValid(token));
    }
}

Projemize Google reCAPTCHA v3 eklemiş olduk. Projemizin kaynak kodlarını bu link (GitHub) üzerinden ulaşabilirsiniz.

ASP.NET Core Google Recaptcha

Bildiğim kadarıyla yazmaya çalıştım. İnşallah birilerin faydalanması dileğiyle..