验证ASP.NET服务器端的Recaptcha 2(无CAPTCHA reCAPTCHA)

Ala*_*laa 66 c# vb.net asp.net recaptcha

新的Recaptcha 2看起来很有希望,但我没有找到在ASP.NET服务器端验证它的方法,

if(Page.IsValid)这个答案中,对旧的Recaptcha有效,但不适用于新的,

如何在服务器端验证新的reCAPTCHA?

Ala*_*laa 141

在阅读了许多资源之后,我最终编写了这个类来处理新ReCaptcha的验证:

如所提到的在这里:当一个验证码是由最终用户,一个新的场(G-验证码响应)解决了将在HTML被填充.

我们需要读取此值并将其传递给下面的类来验证它:

在C#中:

在您的页面背后的代码中:

string EncodedResponse = Request.Form["g-Recaptcha-Response"];
bool IsCaptchaValid = (ReCaptchaClass.Validate(EncodedResponse) == "true" ? true : false);

if (IsCaptchaValid) {
    //Valid Request
}
Run Code Online (Sandbox Code Playgroud)

班级:

  using Newtonsoft.Json;

    public class ReCaptchaClass
    {
        public static string Validate(string EncodedResponse)
        {
            var client = new System.Net.WebClient();

            string PrivateKey = "6LcH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory";

            var GoogleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse));

            var captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<ReCaptchaClass>(GoogleReply);

            return captchaResponse.Success.ToLower();
        }

        [JsonProperty("success")]
        public string Success
        {
            get { return m_Success; }
            set { m_Success = value; }
        }

        private string m_Success;
        [JsonProperty("error-codes")]
        public List<string> ErrorCodes
        {
            get { return m_ErrorCodes; }
            set { m_ErrorCodes = value; }
        }


        private List<string> m_ErrorCodes;
    }
Run Code Online (Sandbox Code Playgroud)

在VB.NET中:

在您的页面背后的代码中:

Dim EncodedResponse As String = Request.Form("g-Recaptcha-Response")
    Dim IsCaptchaValid As Boolean = IIf(ReCaptchaClass.Validate(EncodedResponse) = "True", True, False)

    If IsCaptchaValid Then
        'Valid Request
    End If
Run Code Online (Sandbox Code Playgroud)

班级:

Imports Newtonsoft.Json


Public Class ReCaptchaClass
    Public Shared Function Validate(ByVal EncodedResponse As String) As String
        Dim client = New System.Net.WebClient()

        Dim PrivateKey As String = "6dsfH-v8SerfgAPlLLffghrITSL9xM7XLrz8aeory"

        Dim GoogleReply = client.DownloadString(String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", PrivateKey, EncodedResponse))

        Dim captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(Of ReCaptchaClass)(GoogleReply)

        Return captchaResponse.Success
    End Function

    <JsonProperty("success")> _
    Public Property Success() As String
        Get
            Return m_Success
        End Get
        Set(value As String)
            m_Success = value
        End Set
    End Property
    Private m_Success As String

    <JsonProperty("error-codes")> _
    Public Property ErrorCodes() As List(Of String)
        Get
            Return m_ErrorCodes
        End Get
        Set(value As List(Of String))
            m_ErrorCodes = value
        End Set
    End Property

    Private m_ErrorCodes As List(Of String)

End Class
Run Code Online (Sandbox Code Playgroud)

  • 如果用户不想导入`Newtonsoft.Json`并创建一个完整定义的Json对象,他们可以使用`System.Web.Script.Serialization`中的`JavaScriptSerializer`并反序列化为普通的'ol'对象,如图所示[在此stackexchange答案](http://stackoverflow.com/questions/20079177/deserializing-json-in-visual-basic/20080495#20080495) (7认同)
  • 只是说,Validate函数的结果是小t的结果,因此我把头发拉出来为什么它不起作用. (5认同)
  • 你的回答非常有用Ala.这是我为消除对Newtonsoft的依赖所做的:JavaScriptSerializer js = new JavaScriptSerializer(); MyObject data = js.Deserialize <MyObject>(GoogleReply); var captchaResponse = data.success; return captchaResponse.ToString(); public class MyObject {public string success {get; 组; }} (4认同)
  • 谢谢Ala.一个旁注,在代码中,bool IsCaptchaValid =(ReCaptchaClass.Validate(EncodedResponse)=="True"?true:false);,你不需要?true:false,这是多余的. (2认同)

Pau*_*aul 42

这是一个使用JavaScriptSerializer的版本.感谢Ala提供此代码的基础.

WebConfig应用程序设置 - 在我的案例中,我已将密钥添加到Web.Config,以允许在环境之间进行转换.如果需要,它也可以在这里轻松加密.

<add key="Google.ReCaptcha.Secret" value="123456789012345678901234567890" />
Run Code Online (Sandbox Code Playgroud)

ReCaptcha类 - 一个简单的类,用于将响应参数以及您的秘密发布到Google并对其进行验证.使用.Net JavaScriptSerializer类反序列化响应,并返回true或false.

using System.Collections.Generic;
using System.Configuration;

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 = ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"];

        if (string.IsNullOrEmpty(secret)) return false;

        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;
    }
}
Run Code Online (Sandbox Code Playgroud)

验证响应 -检查G-的Recaptcha -响应形式参数的有效性在控制器(或背后的web表单代码),并采取适当的行动.

var encodedResponse = Request.Form["g-Recaptcha-Response"];
var isCaptchaValid = ReCaptcha.Validate(encodedResponse);

if (!isCaptchaValid)
{
    // E.g. Return to view or set an error message to visible
}   
Run Code Online (Sandbox Code Playgroud)

  • 对于那些对最简单的实现感兴趣的人来说,这似乎是一个很好的解决方案,特别是在不使用Newtonsoft库的情况下. (3认同)
  • 我选择了这个解决方案.简单,好的解释,易于遵循. (2认同)

Not*_*ple 14

大多数答案似乎比需要的更复杂.他们也没有指定有助于防止拦截攻击的IP(https://security.stackexchange.com/questions/81865/is-there-any-reason-to-include-the-remote-ip-when-using- recaptcha).这就是我所确定的

public bool CheckCaptcha(string captchaResponse, string ipAddress)
{
    using (var client = new WebClient())
    {
        var response = client.DownloadString($"https://www.google.com/recaptcha/api/siteverify?secret={ ConfigurationManager.AppSettings["Google.ReCaptcha.Secret"] }&response={ captchaResponse }&remoteIp={ ipAddress }");
        return (bool)JObject.Parse(response)["success"];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 优秀的解决方案。简单有效。 (2认同)
  • 7年后的感谢! (2认同)

Tab*_*man 6

您可以使用"IsValidCaptcha()"方法验证服务器端的google recaptcha.使用以下方法中的"YourRecaptchaSecretkey"替换您的密钥.

Public bool IsValidCaptcha()
 {
  string resp = Request["g-recaptcha-response"];
  var req = (HttpWebRequest)WebRequest.Create
            (https://www.google.com/recaptcha/api/siteverify?secret=+ YourRecaptchaSecretkey + "&response=" + resp);
     using (WebResponse wResponse = req.GetResponse()) 
       {
       using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
         {
          string jsonResponse = readStream.ReadToEnd();
          JavaScriptSerializer js = new JavaScriptSerializer();
          // Deserialize Json
          CaptchaResult data = js.Deserialize<CaptchaResult>(jsonResponse); 
            if (Convert.ToBoolean(data.success))
              {
               return true;
              }
         }
      }
     return false;
 }
Run Code Online (Sandbox Code Playgroud)

同时创建以下类.

public class CaptchaResult
  {
   public string success { get; set; }
  }
Run Code Online (Sandbox Code Playgroud)

参考链接