CAPTCHA (completely automated public Turing test to tell computers and humans apart) reduces the likelihood of automated bots successfully submitting forms on your web site. Google's reCAPTCHA implementation is familiar to users (as these things go), and is a free service. Integrating it within an ASP.NET Core Razor Pages form is straightforward.
Obtain Google API key
The first thing we need to do is to sign up for an API key pair. The latest documentation for this process can be found on the reCAPTCHA Developer's Guide. Google will provide us with a site key and a secret key. I am storing these keys in the Visual Studio Secret Manager so they are not accidentally checked in with version control. To access the Secret Manager, right-click on the project and select "Manage User Secrets...":
No, these are not my real keys...
As part of the sign up process for the reCAPTCHA keys, we specify the domains for which the keys are valid. Be sure to add "localhost" if you are using the keys for your local development environment.
We next add a reference to the reCAPTCHA API script in our page. My layout template has an optional "Scripts" section just before the closing body tag, so I am putting the script there. I am reading the public site key from the application configuration (in our secrets.json):
And that's really it as far as the client-side integration is concerned. When the page is loaded, the API script takes care of handling the user response. Once the CAPTCHA has been successfully verified on the client, a
g-recaptcha-response parameter will be POST-ed along with our form.
On the server, we need to verify that a valid CAPTCHA response was provided. To do this, we take the
g-recaptcha-response parameter that should have been sent with the form, and verify it using Google's API at
https://www.google.com/recaptcha/api/siteverify. Here is a simplified implementation:
There are obviously a lot of ways to customize the behavior on failure. The implementation above returns a generic response to the user--this is really something that a legitimate user should never see. In the unusual case that Google's API is down, we allow the request to proceed, logging the error.
Assuming everything checks out with the CAPTCHA (and any other validation we have on our form), we allow the registration to proceed.