Invisible reCAPTCHA

I’ve previously used the Google one click reCAPTCHA in sites but as the new invisible version is out I figured I’d have a go at getting it to work.

Previously I had the one click reCAPTCHA working as below where the result populated an invisible required field validated using Bootstrap validator which then allowed the form to be submitted.


@section head {
    <script src='https://www.google.com/recaptcha/api.js'></script>
}

@{
    ViewData["Title"] = "Contact";
}

@{
    string contactMessage = (string)ViewData["ContactMessage"];
}

@model ContactForm

<div class="row">
    <div class="col-lg-4 col-md-6 col-xs-12">
        <h2>@ViewData["Title"].</h2>
        @if (!string.IsNullOrEmpty(contactMessage))
        {
            if (contactMessage == "Message sent :)")
            {
                <div class="alert alert-success" role="alert">Message sent :)</div>
            }
            else
            {
                <div class="alert alert-danger" role="alert">contactMessage</div>
            }
        }
        <form asp-controller="Home" asp-action="Contact" method="post" id="ContactForm" data-toggle="validator" role="form">
            <fieldset>
                <div class="item form-group required field">
                    <div class="row">
                        <div class="col-md-4">
                            <label asp-for="FromEmail" class="control-label"></label>
                        </div>
                        <div class="col-md-8">
                            <input asp-for="FromEmail" class="form-control" required />
                            <div class="help-block with-errors"></div>
                        </div>
                    </div>
                </div>
                <div class="item form-group required field">
                    <div class="row">
                        <div class="col-md-4">
                            <label asp-for="Message" class="control-label"></label>
                        </div>
                        <div class="col-md-8">
                            <textarea asp-for="Message" class="form-control" required rows="10"></textarea>
                            <div class="help-block with-errors"></div>
                        </div>
                    </div>
                </div>
				<div class="form-group">
					<div class="captchaDiv">
						<label class="control-label">Before reqistering, please tick the box below to show you are not a robot and select the relevant pictures if asked.</label>
						<div class="g-recaptcha" data-sitekey="<YOUR_KEY>" data-callback="captcha_onclick"></div>
						<input type="text" name="recaptcha" value="" required id="RecaptchaValidator" pattern="1" style="visibility: hidden">
					</div>
				</div>
                <div class="form-group">
                    <button type="button" class="btn btn-primary" id="submit">Send</button>
                </div>
            </fieldset>
        </form>
    </div>
</div>

@section scripts {
    <script src="~/lib/bootstrap-validator/dist/validator.js"></script>
    <script type="text/javascript">
        function captcha_onclick() {
            $('#RecaptchaValidator').val(1);
            $('#ContactForm').validator('validate');
        }
    </script>
}

The new invisible reCAPTCHA isn’t validated before the specified button is clicked, once it is clicked the reCAPTCHA does its stuff and the user is flagged as being human or not, if they are human then the associated javascript function is triggered. The triggered javascript function then needs to POST the form to the controller action and load the returned view using AJAX.


@section head {
    <script src='https://www.google.com/recaptcha/api.js'></script>
}

@{
    ViewData["Title"] = "Contact";
}

@{
    string contactMessage = (string)ViewData["ContactMessage"];
}

@model ContactForm

<div class="row">
    <div class="col-lg-4 col-md-6 col-xs-12">
        <h2>@ViewData["Title"].</h2>
        @if (!string.IsNullOrEmpty(contactMessage))
        {
            if (contactMessage == "Message sent :)")
            {
                <div class="alert alert-success" role="alert">Message sent :)</div>
            }
            else
            {
                <div class="alert alert-danger" role="alert">contactMessage</div>
            }
        }
        <form asp-controller="Home" asp-action="Contact" method="post" id="ContactForm" data-toggle="validator" role="form">
            <fieldset>
                <div class="item form-group required field">
                    <div class="row">
                        <div class="col-md-4">
                            <label asp-for="FromEmail" class="control-label"></label>
                        </div>
                        <div class="col-md-8">
                            <input asp-for="FromEmail" class="form-control" required />
                            <div class="help-block with-errors"></div>
                        </div>
                    </div>
                </div>
                <div class="item form-group required field">
                    <div class="row">
                        <div class="col-md-4">
                            <label asp-for="Message" class="control-label"></label>
                        </div>
                        <div class="col-md-8">
                            <textarea asp-for="Message" class="form-control" required rows="10"></textarea>
                            <div class="help-block with-errors"></div>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <button type="button" class="g-recaptcha btn btn-primary" id="submit" data-sitekey="<YOUR_KEY>" data-callback="submit_form">Send</button>
                </div>
            </fieldset>
        </form>
    </div>
</div>

@section scripts {
    <script src="~/lib/bootstrap-validator/dist/validator.js"></script>
    <script type="text/javascript">
        function submit_form() {
            if ($('#ContactForm').validator('validate')) {
                var formdata = new FormData($('#ContactForm').get(0));

                $.ajax({
                    url: '@Url.Action("Contact", "Home")',
                    type: 'POST',
                    data: formdata,
                    processData: false,
                    contentType: false,
                    success: function(data) {
                        $("body").html(data);
                        }
                });
            } else {
                grecaptcha.reset();
            }
        }
    </script>
}

This works for forms created using tag helpers in ASP.NET MV 6 but should work in all forms.


Leave a Reply

Your email address will not be published. Required fields are marked *