Steve Steve - 3 months ago 29
Vb.net Question

New Google Recaptcha with ASP.Net

I am attempting to get the new Google reCaptcha working in my ASP.NET project and I am having problems getting it to be the new one "I'm not a robot".

I had the old one in there and after doing much research on the developers.google.com web site, everything looks the same (they even point me to a download of the same dll - 1.0.5). So, I got the new keys and put them in and it works but it looks just like the old reCaptcha.

Has anyone gotten the new one to work with their ASP.Net? What am I missing?

EDIT:

So playing around in a test app and searching some other web sites I found that if I create a page like this:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>reCAPTCHA demo: Simple page</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form id="form1" runat="server" action="?" method="POST">
<div>
<div class="g-recaptcha" data-sitekey="My Public Key"></div>
<br/>
<asp:Button ID="Button1" runat="server" Text="Submit" />

</div>
</form>
</body>
</html>


And then in my code-behind (Button1_Click), I do this:

Dim Success As Boolean
Dim recaptchaResponse As String = request.Form("g-recaptcha-response")
If Not String.IsNullOrEmpty(recaptchaResponse) Then
Success = True
Else
Success = False
End If


The
recaptchaResponse
will either be empty or filled in depending on if they are a bot or not. The issue is, I now need to take this response and send it to google with my private key so I can verify that the response was not provided by a bot, in my code-behind, but I cannot figure out how. I tried this (in place of
Success = True
):

Dim client As New System.Net.Http.HttpClient()
client.BaseAddress = New Uri("https://www.google.com/recaptcha/")
client.DefaultRequestHeaders.Accept.Clear()
client.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"))

Dim response As Net.Http.HttpResponseMessage = Await client.GetAsync("api/siteverify?secret=My Private key&response=" + recaptchaResponse)
If (response.IsSuccessStatusCode) Then
Dim CaptchResponse As ReCaptchaModel = Await response.Content.ReadAsAsync(Of ReCaptchaModel)()
Success = CaptchResponse.success
Else
Success = False
End If


But, I could not figure out how to get the async stuff working and I cannot find anything on what
ReCaptchaModel
is, so I found another way to call a web service and get a json response and tried this instead:

Dim request As Net.WebRequest = Net.WebRequest.Create("https://www.google.com/recaptcha/")
Dim Data As String = "api/siteverify?secret=My Private Key&response=" + recaptchaResponse
request.Method = "POST"
request.ContentType = "application/json; charset=utf-8"
Dim postData As String = "{""data"":""" + Data + """}"
'get a reference to the request-stream, and write the postData to it
Using s As IO.Stream = request.GetRequestStream()
Using sw As New IO.StreamWriter(s)
sw.Write(postData)
End Using
End Using
'get response-stream, and use a streamReader to read the content
Using s As IO.Stream = request.GetResponse().GetResponseStream()
Using sr As New IO.StreamReader(s)
'decode jsonData with javascript serializer
Dim jsonData = sr.ReadToEnd()
Stop
End Using
End Using


But, this just gives me the content of the web page at https://www.google.com/recaptcha. Not what I want. The Google page isn't very useful and I am stuck on where to go. I need some help either calling the Google verify service or if anyone has found another way to do this from ASP.NET.

Answer

I had just about given up when I ran across something unrelated that made me think about it again and in a different way. In my last attempt above, I was attempting to pass the private key and recaptcha response as the data, so I tried it in the create of the WebRequest and it worked. Here is the final solution:

Using the same HTML posted above, I created a function that I can call in the button click event where I check the Page.IsValid and call this function:

Private Function IsGoogleCaptchaValid() As Boolean
    Try
        Dim recaptchaResponse As String = Request.Form("g-recaptcha-response")
        If Not String.IsNullOrEmpty(recaptchaResponse) Then
            Dim request As Net.WebRequest = Net.WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=My Private Key&response=" + recaptchaResponse)
            request.Method = "POST"
            request.ContentType = "application/json; charset=utf-8"
            Dim postData As String = ""

            'get a reference to the request-stream, and write the postData to it
            Using s As IO.Stream = request.GetRequestStream()
                Using sw As New IO.StreamWriter(s)
                    sw.Write(postData)
                End Using
            End Using
            ''get response-stream, and use a streamReader to read the content
            Using s As IO.Stream = request.GetResponse().GetResponseStream()
                Using sr As New IO.StreamReader(s)
                    'decode jsonData with javascript serializer
                    Dim jsonData = sr.ReadToEnd()
                    If jsonData = "{" & vbLf & "  ""success"": true" & vbLf & "}" Then
                        Return True
                    End If
                End Using
            End Using
        End If
    Catch ex As Exception
        'Dont show the error
    End Try
    Return False
End Function

I'm sure there are improvements to be made to the code, but it works. I couldn't see adding references to some JSON libraries for reading one thing I just check the string.