First we need to create a reCaptcha instance. You will need a google account for this. Go to here.
To use reCaptcha you first need to create an account, for that you will need a google account, just fill in this screen below, as in our example we are using reCaptcha v2 we will select it in the reCAPTCHA type field in the first step, as we are testing and developing, the domain will be set to localhost, but when going to production be sure to modify this field with your domain.
In this example I will use the reCapathca “I’m not a robot” Checkbox type as seen in the image below:
Once that is done, you will have your keys available, the site key should be used on the front end, and to keep it safe we will use environment variables, since the secret key will be used on back end in nosse web.config
To use reCaptcha I followed the documentation steps, but with the help of a package from yarn to vue, vue-recaptcha, which provides me with a basically ready component, just implement it and capture the event from validation you can see more about it
yarn add vue-recaptcha
yarn add axios
In my dev.env.js where I store my environment variables I will set the site key and url of my api, which in this case will be running on localhost
module.exports = {
NODE_ENV: '"development"',
RECAPTCHA_PUBLIC_KEY:'"6__________yourkey________________c"',
process.env.API_URL: '"http://localhost:55348/api'"
})
I’ll start by creating the post service on my route with the axios that will post to google api and return me an object validating whether or not it was successful
services/recaptchaValidate.js:
import axios from 'axios'
export default {
validate (params) {
return new Promise((resolve, reject) => {
axios.post(`${process.env.API_URL}/recaptcha/validate`, params)
.then(response => {
if (response.data.hasErrors) {
reject(response.data.message)
} else {
resolve(response.data)
}
})
.catch(error => {
if (error.response.data.hasOwnProperty('hasErrors')) {
reject(error.response.data.message)
} else {
reject(error.message)
}
})
})
}
}
This done I created a component for recaptcha in my project named Recaptcha.vue, which will issue my validation to the parent component that will receive my validation to enable or not the forward button.
<template>
<VueRecaptcha :sitekey="this.sitekey" :loadRecaptchaScript="true" @verify="validate"/>
</template>
<script>
import VueRecaptcha from 'vue-recaptcha'
import Validation from '@/services/recaptchaValidate'
export default {
components: {VueRecaptcha},
data () {
return {
sitekey: process.env.RECAPTCHA_PUBLIC_KEY
}
},
methods: {
validate (response) {
Validation.validate({Response: response}).then(result => {
this.$emit('validate', result.objectResult.success)
}).catch(error => console.log(error))
}
}
}
</script>
The Parent component:
<template>
<b-row>
<b-col class="p-5 mb-2">
<div class="text-center justify-center align-center">
<Recaptcha v-if="!logged" @validate="validate"/>
</div>
</b-col>
</b-row>
<b-row no-gutters>
<b-col class="p-0">
<div class="text-center">
<a @click="checkFrom('next')" :class="this.validateRecaptcha ? '' : 'disabled'" class="btn btn-primary text-white m-1">Forward</a>
</div>
</b-col>
</b-row>
</template>
import Recaptcha from '@/components/recaptcha/Recaptcha'
export default {
components: {Recaptcha},
data () {
return {
validateRecaptcha: false
}
},
methods: {
validate (success) {
this.validateRecaptcha = success
}
}
Web.config to store my secret key and the url to google reCaptcha API:
<configuration>
<appSettings>
<add key="RECAPTCHA_SECRET_KEY" value="6______yourkey________o"/>
<add key="RECAPTCHA_GOOGLE_URL" value="https://www.google.com/recaptcha/api/siteverify"/>
</appSettings>
</configuration>
I am creating a model to handle the request that will be received by my route named RecaptchaRequest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Recaptcha.Models.Requests
{
public class RecaptchaRequest
{
public string Response { get; set; }
}
}
I am creating a model to handle the response of google API named RecaptchaResponse.cs:
using System;
using System.Collections.Generic;
using System.Web;
namespace Recaptcha.Models.Responses
{
public class RecaptchaResponse
{
public bool Success { get; set; }
public string Hostname { get; set; }
}
}
I will not go into the details of how my BaseController is made, but it is a set of methods where I manipulate the responses to return the consumer of my route, feel free to do it your own way, because the goal is just show how to access the google API, so below follows my controller named RecaptchaController.cs:
using Recaptcha.Business;
using Recaptcha.Models.Requests;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace Recaptcha.Controllers
{
[RoutePrefix("api/recaptcha")]
public class RecaptchaController : BaseController
{
[HttpPost]
[Route("validate")]
public async System.Threading.Tasks.Task<HttpResponseMessage> ValidateAsync(RecaptchaRequest recaptchaRequest)
{
if (!Token.IsValid)
return GetResponseFromInvalidToken();
var response = await RecaptchaBusiness.RetrieveResponse(recaptchaRequest);
return GetResponseFromResults(HttpStatusCode.OK, "", response);
}
}
}
And finally my Business named RecaptchaBusiness.cs where I make the request via post to google api and get the json that I send to my front, informing if who accessed the checkbox is or is not a robot
using Recaptcha.Models.Requests;
using Recaptcha.Models.Responses;
using System.Collections.Generic;
using System.Configuration;
using System.Net.Http;
namespace Recaptcha.Business
{
public class RecaptchaBusiness
{
private static readonly HttpClient client = new HttpClient();
public static async System.Threading.Tasks.Task<RecaptchaResponse> RetrieveResponse(RecaptchaRequest recaptchaRequest)
{
var values = new Dictionary<string, string>
{
{ "secret", ConfigurationManager.AppSettings["RECAPTCHA_SECRET_KEY"].ToString()},
{ "response", recaptchaRequest.Response}
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync(ConfigurationManager.AppSettings["RECAPTCHA_GOOGLE_URL"].ToString(), content);
var recaptchaResponse = new RecaptchaResponse();
return await response.Content.ReadAsAsync<RecaptchaResponse>();
}
}
}
Remembering that validation cannot be done by the client (front) if you try this, you get that hellish CORS error
I hope this tutorial will surely help and you if you liked this post, please consider sharing it with others.
Thank for reading !
#vue-js #javascript #c-sharp #asp-net