Google reCAPTCHA v3 integration using ASP.NET Core
Today we will be looking into how to integrate the
Google's reCAPTCHA is a free service to protect websites from spam and abuse. For more official details please visit here.
Background
The reCAPTCHA is an additional security layer for a website. Many of the websites are still using reCAPTCHA v2. If Google's reCAPTCHA v2 identifies the website user behaviour or actions triggering on website are suspicious, then reCAPTCHA v2 throws a challenge to the user to prove that human is accessing the website.
Most of the time reCAPTCHA v2 renders as a simple checkbox saying "I'm not a robot." In case if reCAPTCHA v2 is not confident enough that you are really a human then it throws a challenge to you with an image task to prove you are a human. Many times this kind of task is annoying the users.
reCAPTCHA v2 is also vulnerable that an intelligent bots and advanced AI can solve the challenges as well with today's technology.
Having said that, Google listened the challenges faced by users to complete the image task and understanding the vulnerability of reCAPTCHA v2, Google came up with reCAPTCHA v3 for better security and user experience.
Unlike v2, the reCAPTCHA v3 is very transparent to website users. There are no more challenging tasks to users to solve the puzzle. It monitors the website user's behaviour to determine whether they are humans or bots.
reCAPTCHA v3 works based on the score. Meaning that, whenever the request comes to a website the reCAPTCHA v3 return the score between 0 and 1 that represents how likely the request came from human and bot.
If the score is close to 0, then Sorry! you are a bot.
If the score is clsoe to 1, then Congrats! you are a human.
As reCAPTCHA v3 improved the experience of users by eliminating the challenging tasks, it also raises the other problems to website administrators. With reCAPTCHA v3, the website administrators need to taken an aciton based on the score.
The major problem faced by the website administrators is that for what score what action to take up? Let say if the score is 0.18, do we need to block the user assuming it is bot? If the score is 0. 76, do we need to allow the user assuming it is a human? There is no clear answer to this, which makes difficult to take the judgement by website administrators.
In order to integrate the Google's reCAPTCHA v3 in ASP.NET Core (or in any other technology), first you have to register your site in Google reCAPTCHA website. Upon registering the site, you will get Site Key and Secret Key under the site you registered. Copy these two separately to either notepad or whichever editing tool you use.
Register site using below link:
https://www.google.com/recaptcha/admin/create
Once you have registered the site, you will see the keys generated as shown below. Copy these keys and keep aside as we need them in our ASP.NET Core application.
We really not needed any 3rd party and NuGet packages to integrate the reCAPTCHA v3.
Create a new ASP.NET Core Web application (or you can even try the below steps to your existing project). For the demonstration purpose I'm using ASP.NET Core MVC targetting to .NET Core 6.
In first step, configure the keys in appsettings.json file as shown below:
[pre class="brush:css; toolbar: false;" title=""] "GoogleRecaptchaV3Config": { "SiteKey": "6Ld48dUfAAAAABqa_GhXOutOskznWYmU9Zhsdu50", "SecretKey": "6Ld48dUfAAAAAFXoGAlzocI2RdZPFZY9tqE1zc_8", "VerifyURL": "https://www.google.com/recaptcha/api/siteverify" } [/pre]
And, then create the models to hold the above configuration JSON in object format and to hold the response of reCAPTCHA verification under Models folder.
Under Program.cs file, configure the GoogleRecaptchaV3Model to pass as dependency injection object for the controllers.
[pre class="brush:csharp; toolbar: false;" title=""] builder.Services.Configure<GoogleRecaptchaV3Model>(builder.Configuration.GetSection("GoogleRecaptchaV3Config")); [/pre]
The next part is to build the login page and adding reCAPTCHA to it. For this, let's create a login model under the Models folder.
[pre class="brush:csharp; toolbar: false;" title=""] public class LoginModel { public string Username { get; set; } public string Password { get; set; } public string CaptchaToken { get; set; } } [/pre]
Once login model is ready, create a login view with the below code. Make sure you create the view with LoginModel binder.
[pre class="brush:javascript; toolbar: false;" title=""] <form asp-controller="Login" asp-action="LoginMe" method="post" id="fmLogin"> <h2 class="text-center">Log in</h2> <div class="form-group"> <input type="text" class="form-control" placeholder="Username" asp-for="Username"> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="Password" asp-for="Password"> </div> <div class="form-group"> <input type="hidden" asp-for="CaptchaToken" /> <button class="g-recaptcha btn btn-primary btn-block" data-sitekey="@recaptchV3Config.Value.SiteKey" data-callback="onSubmitCallback" data-action="submit"> Log in </button> </div> </form> [/pre]
Make sure you inject the GoogleRecaptchaV3Model to read the reCAPTCHA configuration. As you can see in the above HTML, Log In buton calls a javascript method to accept the token rendered by the reCAPTCHA API.
[pre class="brush:javascript; toolbar: false;" title=""] @model LoginModel @{ ViewData["Title"] = "Login"; Layout = null; @inject IOptions<GoogleRecaptchaV3Model> recaptchV3Config; } <script src="https://www.google.com/recaptcha/api.js"></script> <script type="text/javascript"> function onSubmitCallback(token) { $("#CaptchaToken").val(token); document.getElementById("fmLogin").submit(); } </script> [/pre]
Finally create a login controller to render the login view, handle the login form sumission and validate the reCAPTCHA token.
[pre class="brush:csharp; toolbar: false;" title=""] private readonly GoogleRecaptchaV3Model _recaptchV3Config; public LoginController(IOptions<GoogleRecaptchaV3Model> recaptchV3Config) { _recaptchV3Config = recaptchV3Config.Value; } public IActionResult Index() { return View(); } [HttpPost] public IActionResult LoginMe(LoginModel model) { bool bCaptchValid = IsRecaptchV3Valid(model.CaptchaToken); if (bCaptchValid) { return RedirectToAction("Index", "Home"); } return View(); } bool IsRecaptchV3Valid(string captchaResponseToken) { var reCaptchVerifyUri = $"{_recaptchV3Config.VerifyURL}?secret={_recaptchV3Config.SecretKey}&response={captchaResponseToken}"; HttpClient httpClient = new HttpClient(); HttpResponseMessage responseMessage = httpClient.GetAsync(reCaptchVerifyUri).Result; string responseInJSON = responseMessage.Content.ReadAsStringAsync().Result; GoogleRecaptchaV3Response grcV3Response = JsonConvert.DeserializeObject<GoogleRecaptchaV3Response>(responseInJSON); return grcV3Response!.success; } [/pre]
BINGO!! Now you are done with integration, adding the reCAPTCHA and verification of captcha token. The GoogleRecaptchaV3Response model holds the score, and based on the score you can decide to let the user in or not.
Once you run the application you will see reCAPTCHA rendered on login page as shown below:
You can download the complete source code from GitHub
Hope this article helps you such a way to make easier in the integration processes. Any question? Please use the below commnet box. Happy coding !!!
No comments: