自定义 reCaptcha 验证
如何手动将 reCaptcha 集成到您的网站中。
引言
reCaptcha 是一个非常有用的 Captcha 工具,用于验证访问您网站的访问者是否真的是人类。这主要用于防止垃圾邮件。
这是一个示例 reCaptcha

CodeProject 上有很多自定义 Captcha 解决方案,但 reCaptcha 有一些优势
- 它由 Google 维护 - 因此,如果 captcha 图像被攻破,Google 的更新将解决问题,而无需 Web 开发人员进行任何工作。
- reCAPTCHA 挑战的答案被用于数字化文本文档。
- 您的 Web 服务器不必花费处理器时间来生成 captcha 图像。
- reCaptcha 有一个音频选项,对视力障碍用户很有用。
这些优点都不错,除非您不喜欢 Google。
背景
在为我的网站开发新功能时,我在实现 reCaptcha 时遇到了一些问题。
提供了一个 .NET 服务器控件,但是,我无法让客户端脚本选择我想要使用的主题,所以我决定坚持下去并自己实现它。
Using the Code
注意 - reCaptcha 要求您创建加密密钥。这些密钥用于提高安全性并且易于创建 - 只需 点击此处创建您的密钥,然后将您的密钥添加到演示的 web.config 中。
首先,我们需要设置客户端。
在页面的头部包含 reCaptcha 客户端库
<head>
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js">
</script>
</head>
接下来,添加以下代码
<div id="recaptcha_div"></div>
<script type="text/javascript">
Recaptcha.create("<%=Config.PublicKey %>",
"recaptcha_div", {
lang: "<%=LanguageCode %>",
theme: "clean",
callback: Recaptcha.focus_response_field
});
</script>
如您所见,我们从服务器获取两个值,并直接将其注入到客户端
Config.PublicKey
(这是您的公共 reCaptcha 密钥 - 如果您没有密钥,请前往 此处 获取一个。)LanguageCode
如果您想更改 captcha 使用的主题,可以阅读更多信息 此处。
接下来,服务器端代码。
文章下载包含完整的服务器端代码,在这里我将只概述重要的部分。
将自定义验证器添加到您的页面,并提供以下代码作为其服务器端验证方法
// our custom server validator's validation method
protected void OnRecaptchaValidate(object sender, ServerValidateEventArgs e)
{
string challenge = Request.Form["recaptcha_challenge_field"];
string clientResponse = Request.Form["recaptcha_response_field"];
reCaptchaValidation validator =
new reCaptchaValidation(
Config.Proxy, // if you don't require a proxy to access
// the internet, just comment out this line.
Request.UserHostAddress,
Config.PrivateKey,
challenge,
clientResponse);
e.IsValid = validator.Validate();
if (!e.IsValid)
{
if (validator.IsErrored)
{
// oh dear, something not right
if (validator.Exception != null) // an exception occurred while
// trying to validate
Outcome.Text = validator.Exception.ToString();
else if (validator.ValidationResult != null) // the validation web service
// returned an error code
// (other than an invalid captcha solution)
Outcome.Text = "web service error: " + validator.ValidationResult;
}
}
}
验证被封装在一个名为 reCaptchaValidation
的类中
public class reCaptchaValidation
{
private string challenge, response, privateKey, ip;
private IWebProxy proxy;
public reCaptchaValidation(string clientIP, string privateKey,
string challenge, string response) : this(null, clientIP, privateKey,
challenge, response) { }
public reCaptchaValidation(IWebProxy proxy, string clientIP,
string privateKey, string challenge, string response)
{
this.proxy = proxy;
this.ip = clientIP;
this.privateKey = privateKey;
this.challenge = challenge;
this.response = response;
}
private bool _errored;
public bool IsErrored
{
get
{
return _errored;
}
}
private Exception _ex;
public Exception Exception
{
get
{
return _ex;
}
}
private string _vr;
public string ValidationResult
{
get
{
return _vr;
}
}
public bool Validate()
{
try
{
string post = "privatekey=" + HttpUtility.UrlEncode(privateKey) +
"&remoteip=" + HttpUtility.UrlEncode(ip) + "&challenge=" +
HttpUtility.UrlEncode(challenge) + "&response=" +
HttpUtility.UrlEncode(response);
WebRequest wr = HttpWebRequest.Create
("http://www.google.com/recaptcha/api/verify");
wr.Method = "POST";
if (proxy != null)
wr.Proxy = proxy;
wr.ContentLength = post.Length;
wr.ContentType = "application/x-www-form-urlencoded";
using (StreamWriter sw = new StreamWriter(wr.GetRequestStream()))
{
sw.Write(post);
sw.Close();
}
HttpWebResponse resp = (HttpWebResponse)wr.GetResponse();
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
string valid = sr.ReadLine();
if (valid != null)
{
if (valid.ToLower().Trim() == "false")
{
string errorcode = sr.ReadLine();
if (errorcode != null)
{
if (errorcode.ToLower().Trim() != "incorrect-captcha-sol")
{
_vr = errorcode;
_errored = true;
return false;
}
}
}
return (valid.ToLower().Trim() == "true");
}
else _vr = "empty web service response";
sr.Close();
return false;
}
}
catch (Exception caught)
{
_errored = true;
_ex = caught;
}
return false;
}
}
该类通过将所有必需的信息发布到 Google reCAPTCHA 验证 Web 服务来处理用户 captcha 响应的验证。
我使演示 Web 应用程序尽可能易于使用 - 只需在 web.config 中提供所需的值即可。
历史
- 2010 年 10 月 7 日:发布。