locked
How do you do server validation of response from Google reCAPTCHA using VB.NET? RRS feed

  • Question

  • User695372294 posted

    I have successfully added Google reCAPTCHA V2 with an "I'm not a robot" checkbox to a 'Contact Us' webform, plus an associated HTML Input tag labelled 'Submit' just below the checkbox. However, I am struggling to find any useful examples of VB.NET code for performing a server-based validation of the response after a user clicks on Submit.

    All I want is a simple YES/NO result that will be used to decide if the Send button on my webform should be enabled. Any guidance would be much appreciated.

    Tuesday, December 17, 2019 9:05 PM

Answers

  • User409696431 posted

    Assuming your aspx page has the following:

    <div class="g-recaptcha" data-sitekey="....your key here ....."></div>

    Use a button that posts back to the same page.  In code-behind (C# - you'll need to switch it to VB)

    bool isCaptchaValid;
    protected void Page_Load(object sender, EventArgs e)
    {
       if(Page.IsPostBack)
       {
           var encodedResponse = Request.Form["g-Recaptcha-Response"];
           isCaptchaValid = ReCaptcha.Validate(encodedResponse);
           if(!isCaptchaValid) {//Invalid - handle it for user however you like, including disabling a button on the page.}
           else {//Valid - continue on}
       }
    }
    public class ReCaptcha
    {
        public bool Success { get; set; }
        public List<string> ErrorCodes { get; set; }
        public static bool Validate(string encodedResponse)
        {
            if (string.IsNullOrEmpty(encodedResponse)) return false;
    
            var client = new System.Net.WebClient();
            var secret = "... your secret code here ....";
            var googleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, encodedResponse));
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            var reCaptcha = serializer.Deserialize<ReCaptcha>(googleReply);
            return reCaptcha.Success;
        }
    }
    

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 18, 2019 12:47 AM
  • User409696431 posted

    My code works - it's used in three differnent websites.   My code clearly has one argument. 

    public static bool Validate(string encodedResponse)

    Your's seems not to have any arguments.

    Public Overloads Sub Validate()

    Hopefully the fix is as simple as that.  If not, post your translated VB code.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 18, 2019 6:30 PM

All replies

  • User409696431 posted

    Assuming your aspx page has the following:

    <div class="g-recaptcha" data-sitekey="....your key here ....."></div>

    Use a button that posts back to the same page.  In code-behind (C# - you'll need to switch it to VB)

    bool isCaptchaValid;
    protected void Page_Load(object sender, EventArgs e)
    {
       if(Page.IsPostBack)
       {
           var encodedResponse = Request.Form["g-Recaptcha-Response"];
           isCaptchaValid = ReCaptcha.Validate(encodedResponse);
           if(!isCaptchaValid) {//Invalid - handle it for user however you like, including disabling a button on the page.}
           else {//Valid - continue on}
       }
    }
    public class ReCaptcha
    {
        public bool Success { get; set; }
        public List<string> ErrorCodes { get; set; }
        public static bool Validate(string encodedResponse)
        {
            if (string.IsNullOrEmpty(encodedResponse)) return false;
    
            var client = new System.Net.WebClient();
            var secret = "... your secret code here ....";
            var googleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, encodedResponse));
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            var reCaptcha = serializer.Deserialize<ReCaptcha>(googleReply);
            return reCaptcha.Success;
        }
    }
    

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 18, 2019 12:47 AM
  • User665608656 posted

    Hi haggis999,

    If you want to verify whether Google reCAPTCHA V2 is passed to determine whether the button is enabled, I suggest that you can use the data-callback client click event of Google reCAPTCHA V2 to obtain grecaptcha's response, and then use ajax to verify in the code behind.

    You can refer to this link : https://stackoverflow.com/a/27767239

    For more details, please refer to the following code:

    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script src="../Scripts/jquery-3.0.0.min.js"></script>
        <script type="text/javascript" src='https://www.google.com/recaptcha/api.js?hl=en'></script>
        <script>
            function imNotARobot() {
                var response = grecaptcha.getResponse();
                $.ajax({
                    type: 'POST',
                    url: 'Demo.aspx/ValidateGoogleRecaptcha',
                    data: '{response: "' + response + '"}',
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (results) {
                        if (results.d) {
                            $("#btnLogin").prop('disabled', false);
                        } else {
                            $("#btnLogin").prop('disabled', true);
                        }
                    },
                    error: function () { alert('error'); }
                });
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <div class="g-recaptcha"
                    data-sitekey="YOUR SITE KEY" data-callback="imNotARobot">
                </div>
                <asp:Button ID="btnLogin" runat="server" Text="Check Recaptcha" Enabled="false" />
            </div>
        </form>
    </body>
    </html>
    
        Public Class MyObject
            Public Property success As String
        End Class
    
      <WebMethod>
        Public Shared Function ValidateGoogleRecaptcha(ByVal response As String) As Boolean
            Return ValidateRecaptcha(response)
        End Function
    
        Public Shared Function ValidateRecaptcha(ByVal response As String) As Boolean
            Dim Valid As Boolean = False
            Dim req As HttpWebRequest = CType(WebRequest.Create(" https://www.google.com/recaptcha/api/siteverify?secret=YOUR SECRATE KEY&response=" & response), HttpWebRequest)
            Try
    
                Using wResponse As WebResponse = req.GetResponse()
    
                    Using readStream As StreamReader = New StreamReader(wResponse.GetResponseStream())
                        Dim jsonResponse As String = readStream.ReadToEnd()
                        Dim js As JavaScriptSerializer = New JavaScriptSerializer()
                        Dim data As MyObject = js.Deserialize(Of MyObject)(jsonResponse)
                        Valid = Convert.ToBoolean(data.success)
                    End Using
                End Using
    
                Return Valid
            Catch ex As WebException
                Throw ex
            End Try
        End Function

    Here is the result of this work demo:

    Best Regards,

    YongQing.

    Wednesday, December 18, 2019 6:13 AM
  • User409696431 posted

    That's a rather long winded and complicated answer.  Mine is much simpler, since the post stated the use will click a submit button.  No additional ajax needed, it's a postback.

    Wednesday, December 18, 2019 4:05 PM
  • User695372294 posted

    KathyW

    That's a rather long winded and complicated answer.  Mine is much simpler, since the post stated the use will click a submit button.  No additional ajax needed, it's a postback.

    Hi Kathy,
    I am indeed interested in finding the simplest possible solution to my problem and had already seen some implausibly complex offerings elsewhere before posting here. I've already spent some time trying and failing to get a 'simple' solution I found on YongQing's link to stackoverflow.com and have now turned my attention to yours.

    I've converted your code to VB.NET and placed it in a webform, but I have a problem. The line in the Page_Load sub 'isCaptchaValid = recaptcha.Validate(encodedResponse)' immediately generates the following error in VS 2017, with a wavy line under encodedResponse:

    Too many arguments to 'Public Overloads Sub Validate()'

    Wednesday, December 18, 2019 5:05 PM
  • User409696431 posted

    My code works - it's used in three differnent websites.   My code clearly has one argument. 

    public static bool Validate(string encodedResponse)

    Your's seems not to have any arguments.

    Public Overloads Sub Validate()

    Hopefully the fix is as simple as that.  If not, post your translated VB code.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 18, 2019 6:30 PM
  • User695372294 posted

    My code works - it's used in three differnent websites.   My code clearly has one argument. 

    public static bool Validate(string encodedResponse)

    Your's seems not to have any arguments.

    Public Overloads Sub Validate()

    Hopefully the fix is as simple as that.  If not, post your translated VB code.

    My VB.NET conversion of your code looks like this.

        Private isCaptchaValid As Boolean
    
    
        Public Class MyReCaptcha
            Public Property Success As Boolean
            Public Property ErrorCodes As List(Of String)
    
            Public Shared Function Validate(ByVal encodedResponse As String) As Boolean
                If String.IsNullOrEmpty(encodedResponse) Then Return False
                Dim client = New System.Net.WebClient()
                Dim secret = ConfigurationManager.AppSettings("ReCaptchaPrivateKey")
                Dim googleReply = client.DownloadString(String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, encodedResponse))
                Dim serializer = New System.Web.Script.Serialization.JavaScriptSerializer()
                Dim reCaptcha = serializer.Deserialize(Of MyReCaptcha)(googleReply)
                Return reCaptcha.Success
            End Function
    
        End Class
    
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
            If Page.IsPostBack Then
                Dim encodedResponse = Request.Form("g-Recaptcha-Response")
    
                isCaptchaValid = recaptcha.Validate(encodedResponse)
    
                If isCaptchaValid Then
                    'Temporary code for testing purposes
                    Literal1.Text = "OK"
                Else
                    Literal1.Text = "NOT OK"
                End If
    
            End If
    
        End Sub
    
    

    Wednesday, December 18, 2019 9:42 PM
  • User409696431 posted

    When I use your code, the error I get is that recaptchais not defined in the following line.   I don't get the error you show.

    isCaptchaValid = recaptcha.Validate(encodedResponse)

    With your naming convention, that line should be

    isCaptchaValid = MyReCaptcha.Validate(encodedResponse)

    Wednesday, December 18, 2019 10:07 PM
  • User695372294 posted

    When I use your code, the error I get is that recaptchais not defined in the following line.   I don't get the error you show.

    isCaptchaValid = recaptcha.Validate(encodedResponse)

    With your naming convention, that line should be

    isCaptchaValid = MyReCaptcha.Validate(encodedResponse)

    Well spotted! I changed ReCaptcha to MyReCaptcha to avoid a conflict with some code associated with another solution to my problem and then failed to notice the need to change it in the isCaptchaValid line.

    It's all working now. Many thanks for your help on this.

     smilesmile

    Wednesday, December 18, 2019 10:38 PM
  • User409696431 posted

    I'm glad its working.   To help others with a similar question, please mark my initial reply as the answer.  :)

    Wednesday, December 18, 2019 10:50 PM
  • User695372294 posted

    I do have one other question....

    There is a demo at https://www.google.com/recaptcha/api2/demo that displays the message 'Please verify that you are not a robot' within the reCaptcha box if you click the Submit button without answering the question. How do you code such a message?

    EDIT:  On checking the source of that page, it looked like it was done by exploiting the class 'recaptcha-error-message', but I never quite got that to work the way I wanted, so I just did it by setting the value of Literal1 (ref my coding above) to that message when the reCaptcha question had not been answered. 

    Wednesday, December 18, 2019 11:00 PM