Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • pantryfight 60 posts 84 karma points
    Sep 17, 2015 @ 05:43
    pantryfight
    0

    Recaptcha 2.0 and Umbraco Forms

    Hi folks,

    Are there any plans to integrate Recaptcha 2.0 (https://developers.google.com/recaptcha/) with Umbraco Forms in place of the v1 offering that's in place at the moment?

    Would be really nice if there is, with it being much more user friendly with it's "I'm not a robot" checkbox instead of the word puzzles, and if it can't verify from there it gives you some simple image recognition puzzles.

    Failing that has anyone successfully modified Umbraco Forms to use it?

    cheers, Geoff

  • Comment author was deleted

    Sep 17, 2015 @ 06:17

    Hey Geoff,

    Check out this topic https://our.umbraco.org/forum/umbraco-pro/contour/63765-Upgrading-ReCaptcha-to-the-Im-not-a-robot-version

    It has all the details needed in order to upgrade

  • pantryfight 60 posts 84 karma points
    Sep 17, 2015 @ 07:57
    pantryfight
    0

    Hi Tim, does this work with Umbraco Forms or just Contour?

    I've been trying to implement this using the method specified but both "FormViewEventArgs" and "FormRenderController" don't appear to exist.

    thanks

  • pantryfight 60 posts 84 karma points
    Sep 17, 2015 @ 23:17
    pantryfight
    0

    I've got it working!

    Pretty much same as the linked thread except I swapped out the references of "FormViewEventArgs" to use "FormValidateEventArgs" and swapped "FormRenderController" for "UmbracoFormsController".

    In the FieldType.Recaptcha view I removed the "theme" setting as well, since none of the options apply to Recaptcha 2.0. Only "dark" and "light" are applicable, which aren't available in UF.

    I can provide exact code that I used if anyone needs it but it's pretty much the same with those substitutions.

  • Martin 114 posts 313 karma points
    Sep 18, 2015 @ 06:28
    Martin
    0

    If you have some code, I would very much appreciate to see it.

    Thanks in advance.

  • pantryfight 60 posts 84 karma points
    Sep 18, 2015 @ 10:43
    pantryfight
    0

    OK cool.. here we go..

    First after you've registered your domain with Google's Recaptcha service, you need this tag in your "head" tag:

    <script src='https://www.google.com/recaptcha/api.js'></script>
    

    Then on your application started event (in this case I'm using WebActivatorEX for this so I've got an App_Start directory, but otherwise could be in a Global.asax or anywhere else I suppose:

    UmbracoFormsController.FormValidate += UFEvents.FormValidate;
    

    Then in my "UFEvents" class I've got this:

    public static class UFEvents
    {
        public static void FormValidate(object sender, FormValidationEventArgs e)
    {
        var reCaptchaField = e.Form.AllFields
            .SingleOrDefault(f => f.FieldType.Name == "Recaptcha");
        if (reCaptchaField != null)
        {
            var httpContext = HttpContext.Current;
            var reCaptchaResponse = httpContext.Request["g-recaptcha-response"];
            bool isValid = IsReCaptchaValid(reCaptchaResponse, new HttpRequestWrapper(httpContext.Request));
    
            if (!isValid)
            {
                var controller = sender as Controller;
                controller.ModelState.AddModelError(reCaptchaField.Id.ToString(), "There was a problem verifying your request, please try again.");
            }
        }
    }
    public static bool IsReCaptchaValid(string gResponse, HttpRequestBase request)
        {
            bool isSuccess = false;
    
            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                values["secret"] = ConfigurationManager.AppSettings["ReCaptchaSecretKey"];
                values["response"] = gResponse;
                values["remoteip"] = GetIpAddress(request);
    
                var response = client.UploadValues(ConfigurationManager.AppSettings["ReCaptchaVerificationUrl"], values);
                var responseString = Encoding.Default.GetString(response);
    
                if (!string.IsNullOrEmpty(responseString))
                {
                    JObject o = JObject.Parse(responseString);
                    string successStr = (string)o["success"];
                    bool.TryParse(successStr, out isSuccess);
                }
            }
    
            return isSuccess;
        }
    
    private static string GetIpAddress(HttpRequestBase request)
        {
            // Look for a proxy address first
            var ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    
            // If there is no proxy, get the standard remote address
            if (string.IsNullOrWhiteSpace(ip)
                || string.Equals(ip, "unknown", StringComparison.OrdinalIgnoreCase))
                ip = request.ServerVariables["REMOTE_ADDR"];
            else
            {
                //extract first IP
                var index = ip.IndexOf(',');
                if (index > 0)
                    ip = ip.Substring(0, index);
    
                //remove port
                index = ip.IndexOf(':');
                if (index > 0)
                    ip = ip.Substring(0, index);
            }
    
            return ip;
        }
    }
    

    It's worth noting that I've got the Recapthca client key and secret key as Appsettings in my web.config here instead of using the ones in the forms.config file because I'm using this same code for another non-umbraco-forms form.

    Finally I've just replaced the FieldType.Recaptcha.cshtml file with this:

    @model Umbraco.Forms.Mvc.Models.FieldViewModel
    @{
        var siteKey = ConfigurationManager.AppSettings["ReCaptchaSiteKey"];
    }
     @if (!string.IsNullOrEmpty(siteKey))
    {   
        <div class="g-recaptcha" data-sitekey="@siteKey"></div>
    }
    

    As you'll see I just included the recaptcha div tag with the key from my web.config. I'm sure the server generated tag that was there originally might have included the script tag as well but I was using recaptcha somewhere else so just did it like this. Also didn't bother with themes since Recaptcha 2 just has light and dark and I was happy with the default of light.

  • zedna 7 posts 87 karma points
    Oct 19, 2015 @ 12:51
    zedna
    0

    Hi Geoff,

    i´m new in umbraco system and even not so skilled in .NET, but i´m using Umbraco Forms with reCaptcha and need to upgrade it.

    In Global.asax i have only one line

    <%@ Application Inherits="Umbraco.Web.UmbracoApplication" Language="C#" %>
    

    so should i insert UmbracoFormsController.FormValidate += UFEvents.FormValidate; here?

    and your class UFEvents is in App_Code folder or somewhere else?

    Thanks

  • pantryfight 60 posts 84 karma points
    Oct 19, 2015 @ 22:37
    pantryfight
    0

    Hi Zedna,

    Are you using Visual Studio? Are you comfortable with building/compiling code with it?

    Basically you need to add a codebehind file to the Global.asax in order to add that code to the Application Start event.. but the instructions are slightly different depending on if you're using VS and rebuilding the code or not.

    If you let me know I can give more specific instructions

  • zedna 7 posts 87 karma points
    Oct 20, 2015 @ 07:38
    zedna
    0

    Yes i´m using Visual Studio and Umbraco 7 with shared database and clean installation (from the beginning)

    I was following your steps, so i included API in header I have "UFEvents" class in App_Code folder and i replaced the code in FieldType.Recaptcha.cshtml

    the last step i need to do is insert to correct place

    UmbracoFormsController.FormValidate += UFEvents.FormValidate;
    

    now i can see reCaptcha, but i can send form even without validation, so probably i need this line somewhere

    the problem i have now is, that my class doesn´t inherit from Global.asax

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Umbraco.Web;
    
    namespace MyApplication
    {
        public class MvcApplication : Umbraco.Web.UmbracoApplication
        {
            protected void Application_Start()
            {
                UmbracoFormsController.FormValidate += UFEvents.FormValidate;
            }
        }
    }
    

    and my Global.asax is

    <%@ Application Codebehind="Global.asax.cs" Inherits="MyApplication.MvcApplication" Language="C#" %>
    
  • pantryfight 60 posts 84 karma points
    Oct 20, 2015 @ 09:53
    pantryfight
    0

    To add code to the Application Started event in your Global.asax file you need to add a codebehind file for it.

    First, in Visual Studio, add a new class to the project called Global.asax.cs at the root of the site (whatever directory Global.asax is in)

    In that file, replace the code block starting with "public class Global" with this instead:

    public class CustomGlobal : UmbracoApplication
    {
        protected override void OnApplicationStarted(object sender, EventArgs e)
        {
            base.OnApplicationStarted(sender, e);
    
            UmbracoFormsController.FormValidate += UFEvents.FormValidate; 
        }
    }
    

    If you try to build the project right now you will have an error saying that UFEvents doesn't exist or something like that. Right click the word "UFEvents" in the Global.asax.cs file code and click "Resolove" then click on the appropriate "using" statement that comes up in this menu. You should now be able to build.

    Save this file, and then right click "Global.asax" and click "View Markup". Here, you need to add the "CodeBehind" attribute and edit the "Inherits" attribute like so:

    <%@ Application CodeBehind="Global.asax.cs" Inherits="umb_test.CustomGlobal" Language="C#" %>
    

    Here, change the "umb_test" bit to match whatever the namespace of your Global.asax.cs file is. Whatever comes after "namespace" in that file.

    Build the project and run and that code should now get hit on the (only) on first time the app runs... might help to put a breakpoint in the code while running to see if it's actually getting hit. If you want to try it again, you can effectifely restart the app by touching the web.config file. (just make a tiny change like adding a space somewhere and saving it. This will force IIS to restart the app next time the website is accessed.

  • zedna 7 posts 87 karma points
    Oct 20, 2015 @ 12:11
    zedna
    0

    I did everything exactly the same, but i think my problem is coming from somewhere else, because obviously Global.asax.cs is not inheriting anything.

    <%@ Application CodeBehind="Global.asax.cs" Inherits="MyProject.CustomGlobal" Language="C#" %>
    

    enter image description here

  • pantryfight 60 posts 84 karma points
    Oct 20, 2015 @ 22:38
    pantryfight
    0

    Hi again, you'll need to add the following to the top of your Global.asax.cs file:

    using Umbraco.Forms.Web.Controllers;
    using Umbraco.Web;
    

    Also, I think you might need to create your UFEvents class in a different folder to the "App_Code" folder. Once you do that you'll also need to add another "using" to global.asax.cs to reference the namespace of UFEvents.

Please Sign in or register to post replies

Write your reply to:

Draft