如何设计验证码的实现
<input id="txtUserName" type="text" name="username" class="username" placeholder="请输入您的用户名!">
<input id="txtPassword" type="password" name="password" class="password" placeholder="请输入您的用户密码!">
<input type="Captcha" class="Captcha" name="Captcha" placeholder="请输入验证码!" />
<img src="/Backstage/Home/CheckCode?ID=1" id="imgCode" class="check" alt="单击可刷新" onclick="ChangeCode();" />
@*<a href="javascript:void(0)" onclick="ClickRemoveChangeCode();return false;">看不清</a>*@
<button id="btnLogin" type="submit" class="submit_button">登录</button>
<div class="error"><span>+</span></div>
(1)首先我们看到我们绑定验证码的这里是这样写的,<img src=”/Login/CheckCode?ID=1”>,那么前面的src绑定的地址什么意思呢?他的意思就是我们在Login控制器下面含有一个CheckCode方法来实现验证码的读取
(2)我们要实现验证码,首先我们就要写一个生成验证码的类,没什么难度,网上一搜一大推,下面就是我封装的生成验证码的类,首先我们在LYZJ.UserLimitMVC.Common类库下面新建一个KenceryValidateCode.cs类来存放生成验证码的代码,在这里我们需要给类库引入命名空间System.Drawing。最终的代码如下:
KenceryValidateCode.cs
KenceryValidateCode.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
namespace RBW.Common
{
public class KenceryValidateCode
{
/// <summary>
/// 验证码的最大长度
/// </summary>
public int MaxLength
{
get { return 10; }
}
/// <summary>
/// 验证码的最小长度
/// </summary>
public int MinLength
{
get { return 1; }
}
/// <summary>
/// 生成验证码
/// </summary>
/// <param name="length">指定验证码的长度</param>
/// <returns></returns>
public string CreateValidateCode(int length)
{
int[] randMembers = new int[length];
int[] validateNums = new int[length];
string validateNumberStr = "";
//生成起始序列值
int seekSeek = unchecked((int)DateTime.Now.Ticks);
Random seekRand = new Random(seekSeek);
int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000);
int[] seeks = new int[length];
for (int i = 0; i < length; i++)
{
beginSeek += 10000;
seeks[i] = beginSeek;
}
//生成随机数字
for (int i = 0; i < length; i++)
{
Random rand = new Random(seeks[i]);
int pownum = 1 * (int)Math.Pow(10, length);
randMembers[i] = rand.Next(pownum, Int32.MaxValue);
}
//抽取随机数字
for (int i = 0; i < length; i++)
{
string numStr = randMembers[i].ToString();
int numLength = numStr.Length;
Random rand = new Random();
int numPosition = rand.Next(0, numLength - 1);
validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
}
//生成验证码
for (int i = 0; i < length; i++)
{
validateNumberStr += validateNums[i].ToString();
}
return validateNumberStr;
}
//C# MVC 升级版
/// <summary>
/// 创建验证码的图片
/// </summary>
/// <param name="containsPage">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
public byte[] CreateValidateGraphic(string validateCode)
{
Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 16.0), 30);
Graphics g = Graphics.FromImage(image);
try
{
//生成随机生成器
Random random = new Random();
//清空图片背景色
g.Clear(Color.White);
//画图片的干扰线
for (int i = 0; i < 25; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new Font("Arial", 16, (FontStyle.Bold | FontStyle.Italic));
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(validateCode, font, brush, 3, 2);
//画图片的前景干扰点
for (int i = 0; i < 100; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
//画图片的边框线
g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
//保存图片数据
MemoryStream stream = new MemoryStream();
image.Save(stream, ImageFormat.Jpeg);
//输出图片流
return stream.ToArray();
}
finally
{
g.Dispose();
image.Dispose();
}
}
/// <summary>
/// 得到验证码图片的长度
/// </summary>
/// <param name="validateNumLength">验证码的长度</param>
/// <returns></returns>
public static int GetImageWidth(int validateNumLength)
{
return (int)(validateNumLength * 12.0);
}
/// <summary>
/// 得到验证码的高度
/// </summary>
/// <returns></returns>
public static double GetImageHeight()
{
return 22.5;
}
}
}
(3)那么现在我们的验证码生成的类已经完成了,这时候我们根据<img src=”/Login/CheckCode?ID=1”>所知,我们要到Login控制器下面去创建CheckCode方法来实现能够从View层读取验证码显示出来,那么必然在我们项目当中women就要用到刚才定义的获取验证码的类,那么这时候women就要添加LYZJ.UserLimitMVC.Common的引用,这时候在Login控制器下面的读取验证码的方法代码如下:
/// <summary>
/// 验证码的实现
/// </summary>
/// <returns></returns>
public ActionResult CheckCode()
{
//首先实例化验证码的类
KenceryValidateCode validateCode = new KenceryValidateCode();
//生成验证码指定的长度
string code = validateCode.CreateValidateCode(4);
//将验证码赋值给Session变量
Session["ValidateCode"] = code;
Session.Timeout = 30;
//创建验证码的图片
byte[] bytes = validateCode.CreateValidateGraphic(code);
//最后将验证码返回
return File(bytes, @"image/jpeg");
}
(4)view视图页面
Login.cshtml
Login.cshtml
<script type="text/javascript">
var LoginAndReg;
$(function () {
//登录
function login() {
//$("#btnLogin").click(function () {
//console.info($("#txtPassword").val());
var user = $("#txtUserName").val();
var pass = $("#txtPassword").val();
var code = $(".Captcha").val();
//用户名提醒
if (user == null || user == undefined || user == "") {
ymPrompt.alert({
title: "提示",
message: "请输入用户名!",
maskAlphaColor: "#AF0501"
});
return false;
}
//密码提醒
if (pass == null || pass == undefined || pass == "") {
ymPrompt.alert({
title: "提示",
message: "请输入密码!",
maskAlphaColor: "#AF0501"
});
return false;
}
//验证码提醒
if (code == null || code == undefined || code == "") {
ymPrompt.alert({
title: "提示",
message: "请输入验证码!",
maskAlphaColor: "#AF0501"
});
return false;
}
$.post(
"/Backstage/Home/CheckLogin",
{ txtUsername: user, txtPass: hex_md5(pass), code: code },
function (e) {
//console.info(e.rows.ID);
//alert(e.ID);
if (e.rows.ID != null) {
ymPrompt.succeedInfo({
title: "提示",
message: "登录成功",
maskAlphaColor: "#12A125",
});
window.location.href = "/Backstage/Home/index";
} else {
ymPrompt.errorInfo({
title: "错误",
message: e.message,
maskAlphaColor: '#AF0501',
handler: function () {
$(function () {
$("#txtUserName").attr("value", "");
$(".Captcha").attr("value", "");
})
//自动刷新
window.location.reload();
}
});
}
}, "json"
);
}
function getsize() {
var windowHeight = 0;
var widowWidth = 0;
if (typeof (window.innerHeight) == 'number') {
windowHeight = window.innerHeight;
widowWidth = window.innerWidth;
}
else {
if (document.documentElement && document.documentElement.clientHeight) {
windowHeight = document.documentElement.clientHeight;
widowWidth = document.documentElement.clientWidth;
}
else {
if (document.body && document.body.clientHeight) {
windowHeight = document.body.clientHeight;
widowWidth = document.body.clientWidth;
}
}
}
return { widowWidth, height: windowHeight };
}
$('#btnLogin').click(function () {
login();
//ChangeCode();
return false;
});
//响应键盘的回车事件
//$(this).keydown(function (event) {
// if (event.keyCode == 13) {
// event.returnValue = false;
// event.cancel = true;
// return login();
// }
//});
//$('#txtorgcode').combobox({
// data:orgdata,valueField:'id',textField:'text',panelHeight:'300',160
//})
})
//单击重新改变验证码
function ChangeCode() {
//首先我们获取到验证码的路径
var code = $("#imgCode").attr("src");
//alert(code)
//然后重新给验证码的路径赋值
$("#imgCode").attr("src", code + "1");
//alert($("#imgCode").attr("src", code + "1"))
}
</script>
<body>
<div class="page-container">
<h1>XXXXXX</h1>
<form action="" method="post">
<input id="txtUserName" type="text" name="username" class="username" placeholder="请输入您的用户名!">
<input id="txtPassword" type="password" name="password" class="password" placeholder="请输入您的用户密码!">
<input type="Captcha" class="Captcha" name="Captcha" placeholder="请输入验证码!" />
<img src="/Backstage/Home/CheckCode?ID=1" id="imgCode" class="check" alt="单击可刷新" onclick="ChangeCode();" />
@*<a href="javascript:void(0)" onclick="ClickRemoveChangeCode();return false;">看不清</a>*@
<button id="btnLogin" type="submit" class="submit_button">登录</button>
<div class="error"><span>+</span></div>
</form>
@* <div class="connect">
<p>快捷</p>
</div>*@
</div>
</body>
<div style="text-align: center;">
</div>