使用 jQuery 和 s3capcha 创建 ASP.NET 验证码






4.92/5 (9投票s)
创建一个 ASP.NET 验证码,该验证码可在 Web Forms 或 AJAX 中使用 s3capcha。
引言
s3capcha 是一种简单实用的验证码,它不创建图像文件。它被制作成一个 jQuery 插件,但作者(www.serie3.info)使用 PHP 编写了它。我发现将其代码转换为 ASP.NET 和 C# 非常容易。PHP 代码非常简单,但使用内联配置不是良好的 OOP 风格。我创建了一个易于配置和在应用程序中使用的结构。由于它不创建任何图像,s3capcha 在创建验证码时会降低服务器负载,并且我们还可以将此验证码用于 AJAX 或 MVC 表单。
s3capcha 的工作原理
s3capcha 使用一个简单的模型来创建验证码
- 它会随机化图像的索引。
- 为每个索引、图像分配随机数。
- 从列表中选择一个随机索引。
- 将图像编号放入 session 并将图像列表作为单选按钮发送到客户端;每个单选按钮的值都是一个图像编号。
- 如果用户选择的数字与 session 值匹配,则验证成功。
s3capcha 使用 jQuery 将单选按钮转换为可点击的图像列表。
使用代码
s3capcha
类有三个方法,它们都是静态的。为了防止使用服务器内存进行配置,我将所有配置作为静态变量放置,以便可以重用它们。
第一个方法 shuffle
会随机化数组索引并返回结果。
public static List<int> shuffle(List<int> input)
{
List<int> output = new List<int>();
Random rnd = new Random();
int FIndex;
while (input.Count > 0)
{
FIndex = rnd.Next(0, input.Count);
output.Add(input[FIndex]);
input.RemoveAt(FIndex);
}
input.Clear();
input = null;
rnd = null;
return output;
}
此函数获取输入索引列表并对其进行随机化,然后返回结果。您可以修改此代码以扩展它以随机化任何列表。
在运行验证码之前,需要进行一些配置。原始的 s3capcha
支持两种图像主题,我们需要知道正在使用的主题。有一个 XML 文件用于配置验证码(在 s3capcha 文件夹中)。
<?xml version="1.0" encoding="utf-8" ?>
<s3capcha>
<icons>
<name>apple,cherry,lemon,pear,strawberry</name>
<title>Apple,Cherry,Lemon,Pear,Strawberry</title>
<width>33</width>
<height>33</height>
<ext>jpg</ext>
<folder>fruit</folder>
</icons>
<message>Verify that you are a human not robot, please choose {0}</message>
</s3capcha>
您可以看到可以更改所有验证码字符串,并且没有硬编码的字符串。
name
标签包含将从特定文件夹显示的图像名称。title
标签用于翻译图像;如果您使用英语,则可以使用 name 标签的值,否则可以在此标签中以您的语言放入每个图像名称。
还有额外的图像信息,如 width
和 height
,以及文件扩展名和文件夹名称。文件夹名称必须存在于 s3capcha 中的 icons 文件夹下。
最后的配置是 message
标签。如果您需要翻译或更改客户端浏览器中显示的文本,可以进行更改。不要删除 {0} 标记。它将被替换为用户必须选择的图像名称。
如果您不想使用 XML 文件,可以使用任何方法加载配置。例如,您可以将值作为 App 变量放在 web.config 中。只需更改加载配置的私有方法 LoadConfig
。默认代码将加载 XML 文件。
private static bool LoadConfig()
{
string FilePath = "~/s3capcha/config.xml";
FilePath = HttpContext.Current.Server.MapPath(FilePath);
if (System.IO.File.Exists(FilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(FilePath);
string BaseNode = "/s3capcha/icons/";
XmlNode node = doc.SelectSingleNode(BaseNode + "name");
IconNames = node.InnerText.Split(new char[] { ',' });
node = doc.SelectSingleNode(BaseNode + "title");
IconTitles = node.InnerText.Split(new char[] { ',' });
....
如果配置已加载,该函数必须返回 true
,否则返回 false
。
第二个方法是 GetHtmlCodes
,它渲染验证码的 HTML 代码。它将使用配置;如果没有配置,它将返回错误。
public static string GetHtmlCodes(string PathTo, out int SessionValue)
{
bool HasValue = false;
if (string.IsNullOrEmpty(Message))
HasValue = LoadConfig();
else
HasValue = true;
if (HasValue)
{
Random Rnd = new Random();
int RandomIndex = Rnd.Next(0,IconNames.Length);
List<int> values = new List<int>();
for(int i = 0; i < IconNames.Length;i++)
values.Add(i);
values = shuffle(values);
string WriteThis = "<div class=\"s3capcha\"><p>" +
string.Format(Message, "<strong>" + IconTitles[values[RandomIndex]] +
"</strong>") + "</p>";
int[] RandomValues = new int[IconNames.Length];
for (int i = 0; i < IconNames.Length; i++)
{
RandomValues[i] = Rnd.Next();
WriteThis += string.Format(RowTemplate,
IconTitles[values[i]], RandomValues[i],
PathTo + "/icons/" + Folder + "/" +
IconNames[values[i]] + "." + Extention,
Width, Height);
}
WriteThis += "<div style=\"clear:left\"></div></div>";
SessionValue = RandomValues[RandomIndex];
return WriteThis;
}
else
{
SessionValue = -1;
return "Invalid data, config file not found";
}
}
PathTo
是 s3capcha 文件夹的位置。而 out
值是您需要放入 session 的内容。
所有服务器端代码都已完成,我们可以使用 s3capcha.js 文件。如果我们需要在页面中使用验证码,我们需要导入两个 JS 文件:一个是对 jquery.js 的引用(可以从 jQuery 网站下载),另一个是 s3capcha.js。
有两种方法可以使用:AJAX 或 Web Forms。
在 ASP.NET Web Forms 中使用
为了在 Web Forms 中使用,我在 s3capcha 文件夹中创建了一个用户控件,您可以将其直接拖放到页面上,然后可以使用 IsValid
属性来验证表单。
s3capcha.ascx html 代码
<!-- html codes -->
<script language="javascript" type="text/javascript"
src="<%=ResolveClientUrl("~/s3capcha/s3Capcha.js")%>"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function() {$('#capcha').s3Capcha();});
</script>
<div id="capcha">
<asp:Literal ID="CapchaHTML" runat="server"></asp:Literal>
</div>
我添加了对 s3capcha.js 的引用,但由于寻址问题,我使用了 ResolveClinetUrl
,它被更改并返回了相对地址。
Literal
控件将包含 HTML 代码。这是 s3capcha.ascx 的代码隐藏文件。
public void SetIt()
{
int USessionId;
CapchaHTML.Text =
s3capcha.GetHtmlCodes(ResolveClientUrl("~/s3capcha"),
out USessionId);
Session[s3capcha.s3name] = USessionId;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
SetIt();
}
public bool IsValid
{
get
{
bool res = s3capcha.Verify(Session[s3capcha.s3name],
Request.Form[s3capcha.s3name]);
SetIt();
return res;
}
}
SetIt
将获取 HTML 代码并设置 session 值。IsValid
将使用 s3capcha
类的辅助方法 verify
,该方法仅测试并比较提交的值和 session 值。
创建一个像 default.aspx 这样的 Web Form,并将其拖放到 s3capcha.ascx;然后在您的 postback 按钮函数中使用 IsValid
来验证用户选项。
在 AJAX 表单中使用
对于 AJAX,我们需要两个 ASP.NET 页面。一个页面用于获取 HTML 内容,另一个页面用于提交表单内容和验证用户输入。
我创建了一个名为 s3capcha.ashx(通用处理程序)的页面,它会在每次请求时返回验证码的 HTML 内容并设置 Session 值。
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/html";
int USession;
context.Response.Write(s3capcha.GetHtmlCodes("../../s3capcha", out USession));
context.Session[s3capcha.s3name] = USession;
context.Response.End();
}
另一个通用处理程序是 verify.ashx,它使用了我们用户控件的 IsValid
属性。
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (s3capcha.Verify(context.Session[s3capcha.s3name],
context.Request.Form[s3capcha.s3name]))
context.Response.Write("Success");
else
context.Response.Write("Fail");
context.Response.End();
}
由于处理程序使用 session 值,我们需要继承 IRequiresSessionState
接口。
在客户端页面中,我们需要在表单中放置验证码的位置。通过 AJAX 请求,我们从 s3capcha.ashx 获取结果并将其添加到此位置。
我的示例页面包含(HTML 内容)
<!-- HTML Codes -->
<form id="form1" action="verify.ashx" method="post">
<div id="capcha"></div>
<p><input type="submit" value="submit" /></p>
</form>
我的表单使用 DIV
标签放置验证码内容。对于 JavaScript 代码
//Javascript codes
var getCapcha = function() {
$.ajax({
url: 's3capcha.ashx',
cache: false,
success: function(data) {
$('#capcha').html(data).s3Capcha();
}
});
};
getCapcha
使用 AJAX GET 请求。此外,由于 jQuery 的 cache 参数在 IE 中有效,我们需要禁用它。
现在我们的表单可以工作了,但如果您需要通过 AJAX 提交,可以使用 jQuery forms 插件。目前,我为这个表单创建了一个简单的 Submit 函数。
//Javascript codes
$(document).ready(function() {
getCapcha();
$("form").bind('submit', function() {
$.ajax({
url: 'verify.ashx',
type: 'POST',
data: { 's3capcha': $("input[name=s3capcha]:checked").val() },
cache: false,
success: function(data) {
alert(data);
getCapcha();
}
});
return false;
});
});
查看数据部分以及我向服务器发送的内容。当我渲染验证码内容时,会创建一个名为 "s3capcha" 的单选按钮。我获取选中项的值并将其发送到 verify.ashx 并获取结果。您可以根据需要使用自己的方法。
下载源代码和示例并使用它。有任何想法吗?请在评论区发布。
历史
- 2009/08/12
- 首次发布。