Working on a legacy code component so the current codebase is using HttpHandlers (yes this is and old pre .NET 2.0 application) and the task is to expand this functionality to allow for a Google reCAPTCHA v3 automated valid user detection.

Client side code

Load the appropriate client side script from Google

<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?render=ClientSide_reCAPTCHAv3Token"></script>

Now when the page has loaded run the client side validation to the server HttpHandler code path with the client identifying token.

    <script type="text/javascript">
        $(document).ready(function () {
            grecaptcha.ready(function() {
                grecaptcha.execute('<Google Client reCAPTCA v3 Token>', { action: 'TAG_ACTION' }).then(function (token) {
                    console.log(token);
                    console.log(JSON.stringify({ clientToken: token }));
                    jQuery.ajax({
                        type: "POST",
                        url: "<the_old_handler_path.ashx>",
                        data: JSON.stringify({ clientToken: token }),
                        contentType: "application/json",
                        success: function (response) {
                            console.log(response);
                            if (!response.success) {
                                window.location.href = "/";
                            }
                        }
                    });
                });
            });
        });
    </script>

Handler Code

Important note to read the application/json from the submitted jQuery POST

Que ¬°Important!

var postedData = new StreamReader(context.Request.InputStream).ReadToEnd();

public void ProcessRequest(HttpContext context)
{
	var responseText = JsonConvert.SerializeObject(new
	{
		success = false
	});
	var postedData = new StreamReader(context.Request.InputStream).ReadToEnd();
	if (!string.IsNullOrEmpty(postedData))
	{
		var parsedData = JsonConvert.DeserializeObject<RecaptchaToken>(postedData);
		var secret = ConfigurationManager.AppSettings["reCAPTCHA"];

		var verification = AsyncHelper.RunSync(async () => await ValidateCaptcha(parsedData.ClientToken, secret));
		responseText = JsonConvert.SerializeObject(new
		{
			success = verification.Success,
			errors = verification.ErrorCodes
		});
	}
	context.Response.ContentType = JsonMimeType;
	context.Response.Write(responseText);
}

Also of note to call the async method synchronously this static helper class of AsyncHelper is used

    internal static class AsyncHelper
    {
        private static readonly TaskFactory MyTaskFactory = new
            TaskFactory(CancellationToken.None,
                TaskCreationOptions.None,
                TaskContinuationOptions.None,
                TaskScheduler.Default);

        public static TResult RunSync<TResult>(Func<Task<TResult>> func)
        {
            return AsyncHelper.MyTaskFactory
                .StartNew(func)
                .Unwrap()
                .GetAwaiter()
                .GetResult();
        }
    }