2014-12-16 2 views
4

Я пытаюсь получить новый Google reCaptcha, работающий в моем проекте ASP.NET, и у меня возникают проблемы с его новым «Я не робот».Новый Google Recaptcha с ASP.Net

У меня был старый, и после много исследований на веб-сайте developers.google.com все выглядит одинаково (они даже указывают на загрузку одной и той же библиотеки - 1.0.5). Итак, я получил новые ключи и ввел их, и он работает, но выглядит так же, как старый reCaptcha.

Кто-нибудь получил новый, чтобы работать со своим ASP.Net? Что мне не хватает?

EDIT:

Так, играя в тестовом приложении и поиска некоторые другие веб-сайты, я обнаружил, что если я создаю страницу, как это:

<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> 

И тогда в моем коде, за (Button1_Click), я делаю это:

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 

recaptchaResponse будет либо пустым, либо заполняется в зависимости от того, если y - бот или нет. Проблема в том, что теперь мне нужно принять этот ответ и отправить его в Google с помощью моего личного ключа, чтобы я мог убедиться, что ответ не был предоставлен ботом в моем коде, но я не могу понять, как это сделать. Я попробовал это (вместо 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 

Но я не мог понять, как получить асинхронный материал работает, и я не могу найти ничего о том, что ReCaptchaModel, поэтому я нашел еще один способ вызова веба услуг и получить ответ JSon и попытался вместо этого:

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 

Но, это только дает мне содержание веб-страницы на https://www.google.com/recaptcha. Не то, что я хочу. Google page не очень полезен, и я застрял на том, куда идти. Мне нужна помощь либо при вызове службы проверки Google, либо если кто-то нашел другой способ сделать это из ASP.NET.

+0

Второй ответ работал для меня. Если вы сработали для вас, тогда вы можете выбрать один из них как правильный, чтобы будущие люди могли узнать, какое решение использовать. Просто предложение :) – Greesemonkey3

ответ

6

Я только что сдался, когда столкнулся с чем-то несвязанным, что заставило меня задуматься об этом еще раз и по-другому. В моей последней попытке я попытался передать секретный ключ и ответ recaptcha в качестве данных, поэтому я попробовал его в create WebRequest, и он сработал. Вот окончательное решение:

Используя тот же HTML размещен выше, я создал функцию, что я могу позвонить в случае нажатия кнопки, где я проверить Page.IsValid и вызвать эту функцию:

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 Конечно, в коде есть улучшения, но он работает. Я не мог видеть добавление ссылок на некоторые библиотеки JSON для чтения одной вещи, которую я просто проверяю на строку.

+0

BTW, JSON, возвращенный сервисом, немного изменился на днях, так что он потерпел неудачу. Я бы предложил прочитать JSON иначе, чем показано выше. – Steve

+0

Да, JSON изменился, рассмотрите возможность использования jsonData.Contains ("" "success" ": true") в качестве проверки – EvalKeneval

0

Благодарим вас за это. Это сработало для меня. Я пошел вперед и преобразовал его в C# (так как это то, что я использовал) и добавил несколько вещей.

  • Я изменил шаг проверки. Я разделил строку JSON и оценил, был ли найден успех, где он должен быть.
  • Я использовал ConfigurationManager для хранения ключей ReCaptcha.
  • Наконец, я изменил его с использованием WebRequest на использование и HttpClient. Это сокращает код пополам, потому что теперь мне не нужно читать поток.

Не стесняйтесь использовать этот код.

private static bool IsReCaptchaValid(string response) 
{ 
    if (string.IsNullOrWhiteSpace(response)) 
    { 
     return false; 
    } 

    var client = new HttpClient(); 
    string result = 
     client.GetStringAsync(string.Format("{0}?secret={1}&response={2}", ConfigurationManager.AppSettings["ReCaptchaValidationLink"], 
      ConfigurationManager.AppSettings["ReCaptchaSecretKey"], response)).Result; 
    string[] split = result.Split('\"'); 

    return split[1] == "success"; 
} 
0

Я взял несколько иной подход, используя data-callback параметр и параметр Session. Ниже находится в пределах MainContent блока .aspx файла:

<asp:ScriptManager ID="scrEnablePage" EnablePageMethods="true" runat="server" /> 
<asp:Panel ID="pnlCaptcha" runat="server" Visible="true"> 
    <div class="g-recaptcha" 
     data-sitekey='<asp:Literal ID="litKey" runat="server" Text="<%$ AppSettings:recaptchaPublicKey%>" />' 
     data-callback="handleCaptcha"></div> 
</asp:Panel> 
<script src="https://www.google.com/recaptcha/api.js" async defer></script> 
<script type="text/javascript"> 
    function handleCaptcha(e) { 
     PageMethods.RecaptchaValid(e); 
     location.reload(true); 
    } 
</script> 

Затем в коде-за:

Private Const GoogleUrl As String = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}" 

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    pnlCaptcha.Visible = Not (Session("VerifiedHuman") = "True") 
    ... 
End Sub 

<System.Web.Services.WebMethod(EnableSession:=True)> _ 
Public Shared Sub RecaptchaValid(response As String) 

    Dim client As New System.Net.WebClient() 
    Dim outcome As Dictionary(Of String, String) 
    Dim result As String = String.Join(vbCrLf, 
             {"{", """success"": true", "}"}) 
    Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer() 

    Dim url As String = String.Format(GoogleUrl, 
             ConfigurationManager.AppSettings.Get("recaptchaPrivateKey"), 
             response) 

    Try 
     result = client.DownloadString(url) 
    Catch ex As System.Net.WebException 
     Exit Sub ' Comment out to default to passing 
    End Try 

    outcome = serializer.Deserialize(Of Dictionary(Of String, String))(result) 
    HttpContext.Current.Session("VerifiedHuman") = outcome("success") 

End Sub 

Теперь в Page_Load вы можете проверить Session("VerifiedHuman") = "True" и обновлять элементы управления страницы соответственно, скрывая панель с элементом Captcha и отображением других соответствующих элементов.

Обратите внимание, что это берет ключи от Web.config, т.е.

<configuration> 
    <appSettings> 
    <add key="recaptchaPublicKey" value="..." /> 
    <add key="recaptchaPrivateKey" value="..." /> 
    ... 
    </appSettings> 
    ... 
</configuration> 
0

Это добавляет несколько вещей. Он преобразует ответ от Google в объект Json, он добавляет тайм-аут запроса проверки и добавляет проверку имени хоста (требуется Google при отправке запросов из нескольких доменов, а домены не указаны в области администратора Google).

Imports Newtonsoft.Json 
Public Class Google 
Public Class ReCaptcha 

Private Const secret_key = "YOUR_SECRET_KEY" 

Public Shared Function Validate(Request As HttpRequest, hostname As String) As Boolean 
    Dim g_captcha_response = Request.Form("g-recaptcha-response") 
    If Not String.IsNullOrEmpty(g_captcha_response) Then 
    Dim response = ExecuteVerification(g_captcha_response) 
    If Not response.StartsWith("ERROR:") Then 
     Dim json_obj = JsonConvert.DeserializeObject(Of ValidateResponse)(response) 
     If json_obj.success Then 
     If json_obj.hostname.ToLower = hostname.ToLower Then Return True 
     End If 
    End If 
    End If 
    Return False 
End Function 

Private Shared Function ExecuteVerification(g_captcha_response As String) As String 
    Dim request As Net.WebRequest = Net.WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=" & secret_key & "&response=" & g_captcha_response) 
    request.Timeout = 5 * 1000 ' 5 Seconds to avoid getting locked up 
    request.Method = "POST" 
    request.ContentType = "application/json" 
    Try 
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes("") 
    request.ContentLength = byteArray.Length 
    Dim dataStream As Stream = request.GetRequestStream() 
    dataStream.Write(byteArray, 0, byteArray.Length) 
    dataStream.Close() 
    Dim response As Net.WebResponse = request.GetResponse() 
    dataStream = response.GetResponseStream() 
    Dim reader As New StreamReader(dataStream) 
    Dim responseFromServer As String = reader.ReadToEnd() 
    reader.Close() 
    response.Close() 
    Return responseFromServer 
    Catch ex As Exception 
    Return "ERROR: " & ex.Message 
    End Try 
End Function 

Public Class ValidateResponse 
    Public Property success As Boolean 
    Public Property challenge_ts As DateTime 
    Public Property hostname As String 
    <JsonProperty("error-codes")> 
    Public Property error_codes As List(Of String) 
End Class 

End Class 

End Class 

Так Нажмите событие кнопки, просто позвоните:

If Google.ReCaptcha.Validate(Request, Request.Url.Host) Then 
    ' good to go 
Else 
    ' validation failed 
End If 
Смежные вопросы