Reputation: 84
Our goal is to get Google Recaptcha V3 working on a single form on an MVC3 .NET4.5 project. However, I'm struggling to make this work due to the async request to Google for the Recaptcha score.
FE is set up. I set the new token to a hidden field and send the token to the controller. Then, I run this async task and make the validation request to Google. The response comes back with the success message and the score.
I thought I finally had it working using Task.Factory.StartNew(), but it results in System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult] showing up on the returned view.
Note: It is not an option to upgrade legacy ASP.NET MVC3 project to MVC4.
The hidden field in the view: `
// Other code
@Html.HiddenFor(model => model.Token, new { id="SubscriptionFormModelToken"})
// Other code
`
The token gets set to the hidden field in the JS: ` var your_site_key = '@System.Configuration.ConfigurationManager.AppSettings["ReCaptchaV3PublicKey"]'; console.log('your_site_key', your_site_key);
$(function () {
grecaptcha.ready(function () {
grecaptcha.execute('@System.Configuration.ConfigurationManager.AppSettings["ReCaptchaV3PublicKey"]', { action: 'submit' }).then(function (token) {
// Set token to hidden field for BE validation
console.log('newest token:', token);
var subscriptionFormModelElement = document.getElementById("SubscriptionFormModelToken");
subscriptionFormModelElement.value = token;
console.log('subscriptionFormModelElement:', subscriptionFormModelElement);
});
});
})
</script>
`
Pass the token in and run the task: ` [HttpPost] public async Task SubmitSubscriptionForm(SubscriptionFormModel model, FormCollection collection) {
//Fetch Google Recaptcha result
var captchaObject = Task.Factory.StartNew(() => GoogleCaptchaService.VerifyToken(model.Token));
var captchaResult = captchaObject.Result.Result;
if (!captchaResult)
{
model.RecaptchaResponseIsGood = false;
return PartialView("Subscription/_SubscriptionForm", model);
}
// A lot of other code runs to save the Form Results to the db if captchaResult is successful.
}
`
Task runs through. Response comes back with success/fail and the score: `public class GoogleCaptchaService {
//Google Recaptcha V3 server-side validation
public static async Task<bool> VerifyToken(string token)
{
try
{
var url = $"https://www.google.com/recaptcha/api/siteverify?secret={@System.Configuration.ConfigurationManager.AppSettings["ReCaptchaV3PrivateKey"]}&response={token}";
using (var client = new HttpClient())
{
var httpResult = await client.GetAsync(url);
var responseString2 = httpResult.Content.ReadAsStringAsync().Result;
if (!httpResult.IsSuccessStatusCode)
{
return false;
}
var googleResult = JsonConvert.DeserializeObject<CaptchaResponse>(responseString2);
if (googleResult.Success && googleResult.Score >= 0.5)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception e)
{
return false;
}
}
}`
After all this, the form submits and a partial view is returned, but this appears on the view: System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult].
Upvotes: 0
Views: 73