前言

最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果:

总体来说效果还是可以的,官方提供的SDK也比较详细,可配置性很高。在这里在简单啰嗦几句使用方式:

使用步骤

①进入官网下载sdk接口→ http://www.geetest.com/install/ ,因为小弟是做C#的,所以此处选择C#,具体选择看各位大佬所用语言决定~

②第二步,获取代码,访问红框所示地址,下载demo。

③运行Demo(src文件夹里面的GeetestSDK项目)

④移植到自己项目中

⑴先将上述src文件拷贝到本地项目根目录下面

⑵然后打开本地项目并添加现有项目,将GeetestSDK添加进来

⑶在本地项目中添加引用

⑷View中新建容器存放验证码

  @using (Html.BeginForm())
{
<div>
用户名:
</div>
<div>
@Html.TextBoxFor(model => model.Name)
</div>
<div>
密码:
</div>
<div>
@Html.PasswordFor(model => model.Age)
</div>
<div>
验证码:<div id="captcha"></div> @*新增的存放验证码的容器*@
</div>
<div>
<input type="submit" value="登陆" />
</div>
}

界面入下图:

⑸新建一个控制器(GetcaptchaController)和分部视图(Index)用于显示请求到的页面

控制器代码

     public ActionResult Index()
{
Response.ContentType = "application/json";
Response.Write(getCaptcha());
Response.End();
return View();
}
private String getCaptcha()
{
GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
String userID = "ShowTime";
Byte gtServerStatus = geetest.preProcess(userID);
Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus;
Session["userID"] = userID;
return geetest.getResponseStr();
}

其中,GeetestConfig是新建的一个类,里面代码如下:

 public const String publicKey = "b46d1900d0a894591916ea94ea91bd2c";
public const String privateKey = "36fc3fe98530eea08dfc6ce76e3d24c4";

注:需要引入此命名空间 using GeetestSDK;

Index视图里面放一个空div就行,代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<form id="form1">
<div> </div>
</form>
</body>
</html>

⑹使用Ajax在登录页加载分部视图Index用于显示验证码

     var handler = function (captchaObj) {
//将验证码加到id为captcha的元素里
captchaObj.appendTo("#captcha");
};
//极验
$.ajax({
// 获取id,challenge,success(是否启用failback)
url: "/Getcaptcha/Index",
type: "get",
dataType: "json", // 使用jsonp格式
success: function (data) {
// 使用initGeetest接口
// 参数1:配置参数,与创建Geetest实例时接受的参数一致
// 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
initGeetest({
gt: data.gt,
challenge: data.challenge,
product: "float", // 产品形式
offline: !data.success
}, handler);
}
});

注:需在头部引入Jquery1.9可直接引入下面两个js

<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script src="http://static.geetest.com/static/tools/gt.js"></script>

⑺在登陆按钮中判断验证是否通过,登陆的Index代码如下:

     [HttpPost]
public ActionResult Index(Models.HelloModel loginModel)
{
GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
Byte gt_server_status_code = (Byte)Session[GeetestLib.gtServerStatusSessionKey];
String userID = (String)Session["userID"];
int result = ;
String challenge = Request.Form.Get(GeetestLib.fnGeetestChallenge);
String validate = Request.Form.Get(GeetestLib.fnGeetestValidate);
String seccode = Request.Form.Get(GeetestLib.fnGeetestSeccode);
if (gt_server_status_code == ) result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
else result = geetest.failbackValidateRequest(challenge, validate, seccode);
if (result == ) Response.Write("success");//返回1则表明验证通过,可跳转页面或者做其他处理
else Response.Write("fail");
return View();
}

运行效果

另:官方Demo下载下来是使用的嵌入式的验证效果,要更改此效果,可参考客户端SDK参数来配置

链接→ http://www.geetest.com/install/sections/idx-client-sdk.html#id19

Demo下载

链接:  点我下载  密码:63pd

常规验证码

最终效果

HTML

 <div style="MARGIN-TOP: 12px; margin-left: 0px; width: 130px; float: left;" id="checkInputLine" class="loginFormIpt showPlaceholder">
<input id="checkInput" class="loginFormCheckCodeInput" title='Please enter the contents of the right picture' tabindex="4" maxlength="5" require="True" title='验证码' placeholder="验证码" type="text" name="vcode" />
</div>
<!-- 请输入验证码-->
&nbsp;&nbsp;
<img id="checkloing" src="/Home/VCode" class="loginFormCheckCodeImg" onclick="reloadcode('/Home/VCode')" title="Can not see clearly, change one." />

Ajax 请求如下:

//刷新验证码
function reloadcode(srcStr) {
document.getElementById("checkloing").src = srcStr + "?rand=" + Math.random();
}
var checkInfo = "";
//检查数据
function Check() {
checkInfo = "";
//检查不能为空的数据
$("input[Require='True']").each(function (i) {
var tmpName = $(this).attr("name");
var strVal = $(this).val();
strVal = strVal.replace(/\s/g, "")
if (!strVal)
checkInfo += $(this).attr("placeholder") + "不能为空。<br/>";
});
if (checkInfo) return false;
return true;
}
$(function () {
$("#btnLogin").click(function () {
var ii = layer.load();
if (!Check()) {
layer.close(ii);
layer.msg('' + checkInfo, function () { });
return;
}
$("#loadingDiv").show();
$.ajax({
url: "/Home/Index",
type: "post",
data: "userName=" + $("#tbUserName").val() + "&pwd=" + $("#tbPWD").val() + "&code=" + $("#checkInput").val(),
success: function (data) {
debugger;
if (data.Result == "0") {
layer.close(ii);
layer.msg('' + data.MSG);
return;
} else if (data.Result == "1") {
layer.close(ii);
window.location.href = "/Home/Index";
}
},
error: function (data) {
layer.close(ii);
layer.msg('' + data.MSG);
}
});
});
});

其中:

 layer.msg('' + data.MSG); 这种弹框方式使用了layer弹出层

Home控制器里面的VCde方法就是获取到最新的验证码,代码如下:

 [AllowAnonymous]//跳过登陆验证
public ActionResult VCode()
{
VerificationCodeHelper vcode = new VerificationCodeHelper();
string codeStr = vcode.GetRandomCode();
if (!string.IsNullOrEmpty(codeStr))
{
byte[] arrImg = vcode.GetVCode(codeStr);
Session["code"] = codeStr;
return File(arrImg, "image/gif");
}
else
{
return RedirectToAction("/Login/VCode?rand=" + Guid.NewGuid().ToString().Substring(, ), "image/jpeg");
}
}

其中 VerificationCodeHelper  就是封装好的 生成验证码的类,直接使用就行,代码如下:

  public class VerificationCodeHelper
{
private static Color BackColor = Color.White;
private static int Width = ;
private static int Height = ;
private Random _random;
// private string _code; private int _brushNameIndex; public byte[] GetVCode(string codeStr)
{
_random = new Random();
using (Bitmap img = new Bitmap(Width, Height))
{
// _code = GetRandomCode();
// System.Web.HttpContext.Current.Session["vcode"] = _code;
using (Graphics g = Graphics.FromImage(img))
{
g.Clear(Color.White);//绘画背景颜色 Paint_Text(g, codeStr);// 绘画文字
// g.DrawString(strCode, new Font("微软雅黑", 15), Brushes.Blue, new PointF(5, 2));// 绘画文字
Paint_TextStain(img);// 绘画噪音点
g.DrawRectangle(Pens.DarkGray, , , Width - , Height - );//绘画边框
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
//将图片 保存到内存流中
img.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
//将内存流 里的 数据 转成 byte 数组 返回
return ms.ToArray();
}
}
} } /// <summary>
/// 绘画文字
/// </summary>
/// <param name="g"></param>
private void Paint_Text(Graphics g, string code)
{
g.DrawString(code, GetFont(), GetBrush(), , );
} /// <summary>
/// 绘画文字噪音点
/// </summary>
/// <param name="g"></param>
private void Paint_TextStain(Bitmap b)
{
string[] BrushName = new string[] { "OliveDrab",
"ForestGreen",
"DarkCyan",
"LightSlateGray",
"RoyalBlue",
"SlateBlue",
"DarkViolet",
"MediumVioletRed",
"IndianRed",
"Firebrick",
"Chocolate",
"Peru",
" enrod"
}; for (int n = ; n < ; n++)
{
int x = _random.Next(Width);
int y = _random.Next(Height);
b.SetPixel(x, y, Color.FromName(BrushName[_brushNameIndex])); } }
/// <summary>
/// 随机取一个字体
/// </summary>
/// <returns></returns>
private Font GetFont()
{
string[] FontItems = new string[]{ "Arial",
"Helvetica",
"Geneva",
"sans-serif",
"Verdana"
}; int fontIndex = _random.Next(, FontItems.Length);
FontStyle fontStyle = GetFontStyle(_random.Next(, ));
return new Font(FontItems[fontIndex], , fontStyle);
}
/**/
/**/
/**/
/// <summary>
/// 随机取一个笔刷
/// </summary>
/// <returns></returns>
private Brush GetBrush()
{
Brush[] BrushItems = new Brush[]{ Brushes.OliveDrab,
Brushes.ForestGreen,
Brushes.DarkCyan,
Brushes.LightSlateGray,
Brushes.RoyalBlue,
Brushes.SlateBlue,
Brushes.DarkViolet,
Brushes.MediumVioletRed,
Brushes.IndianRed,
Brushes.Firebrick,
Brushes.Chocolate,
Brushes.Peru,
Brushes.Goldenrod
}; int brushIndex = _random.Next(, BrushItems.Length);
_brushNameIndex = brushIndex;
return BrushItems[brushIndex];
}
/// <summary>
/// 绘画背景颜色
/// </summary>
/// <param name="g"></param>
private void Paint_Background(Graphics g)
{
g.Clear(BackColor);
}
/**/
/**/
/**/
/// <summary>
/// 取一个字体的样式
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
private FontStyle GetFontStyle(int index)
{
switch (index)
{
case :
return FontStyle.Bold;
case :
return FontStyle.Italic;
default:
return FontStyle.Regular;
}
} /// <summary>
/// 取得一个 4 位的随机码
/// </summary>
/// <returns></returns>
public string GetRandomCode()
{
return Guid.NewGuid().ToString().Substring(, );
}
}

注意,初次加载页面的时候,将拿到的code存入Session中,点击登录的时候,将用户输入的验证码传入后台,进行比对验证是否和Session中的验证码相同,如果相同,则允许登录,否则,验证码错误

参考Action如下:

  [HttpPost]
public ActionResult Index(string userName, string pwd)
{
try
{
string vccode = Request.Form["code"];
if (string.IsNullOrEmpty(vccode))
return Json(new { Result = "", MSG = "请填写验证码" });
else
{
if (Session["code"] == null)
return Json(new { Result = "", MSG = "验证码已过期,请点击刷新验证码" });
string str = Session["code"].ToString();
str = str.ToLower();
vccode = vccode.ToLower();
if (str != vccode)
return Json(new { Result = "", MSG = "验证码填写错误!" });
else
{
Session["code"] = null;
}
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(pwd))
{
return Json(new { Result = "", MSG = "用户或密码没有填写" });
}
//查询此用户
#region 查询此用户
List<Models.MySqlUser> adminml = new List<Models.MySqlUser>();
Models.MySqlUser admin = new Models.MySqlUser();
adminml = IBCodeBll.GetModelList(userName.Trim()); if (adminml.Count > )
{
if (!adminml[].password.ToLower().Equals(Maticsoft.Common.DEncrypt.DESEncrypt.Encrypt2(pwd.Trim()).ToLower()))
{
return Json(new { Result = "", MSG = "密码错误!" });
}
}
else
{
return Json(new { Result = "", MSG = "用户不在在!" });
}
#endregion
Session["UserName"] = userName.Trim().ToString();
return Json(new { Result = "", MSG = "登录成功!" });
}
}
catch (Exception ex)
{ return Json(new { Result = "", MSG = ex.Message });
}
}

End!

随手记_C#验证码的更多相关文章

  1. .net点选验证码实现思路分享

    哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个. 先上效果图 如果你被这个效果吸引了就请继续看下去. 贴代码前先说点思路: 1.要有一个汉字库,并按字形分类.(我在数据库里是安部首分类 ...

  2. 【探索】无形验证码 —— PoW 算力验证

    先来思考一个问题:如何写一个能消耗对方时间的程序? 消耗时间还不简单,休眠一下就可以了: Sleep(1000) 这确实消耗了时间,但并没有消耗 CPU.如果对方开了变速齿轮,这瞬间就能完成. 不过要 ...

  3. TODO:Laravel增加验证码

    TODO:Laravel增加验证码1. 先聊聊验证码是什么,有什么作用?验证码(CAPTCHA)是"Completely Automated Public Turing test to te ...

  4. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  5. WPF做12306验证码点击效果

    一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...

  6. 零OCR基础6行代码实现C#验证码识别

    这两天因为工作需要,要到某个网站采集信息,一是要模拟登陆,二是要破解验证码,本想用第三方付费打码,但是想想网上免费的代码也挺多的,于是乎准备从网上撸点代码下来,谁知道,撸了好多个都不行,本人以前也没接 ...

  7. ASP.NET中画图形验证码

    context.Response.ContentType = "image/jpeg"; //生成随机的中文验证码 string yzm = "人口手大小多少上中下男女天 ...

  8. asp.net mvc 验证码

    效果图 验证码类 namespace QJW.VerifyCode { //用法: //public FileContentResult CreateValidate() //{ // Validat ...

  9. ecshop验证码

    <?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...

随机推荐

  1. Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

    将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...

  2. 冒泡,setinterval,背景图的div绑定事件,匿名函数问题

    1.会冒泡到兄弟元素么? $(function(){ $("#a").click(function(){alert("a")}) $("#b" ...

  3. jQuery之Deferred源码剖析

    一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...

  4. nodejs模块发布及命令行程序开发

    前置技能 npm工具为nodejs提供了一个模块和管理程序模块依赖的机制,当我们希望把模块贡献出去给他人使用时,可以把我们的程序发布到npm提供的公共仓库中,为了方便模块的管理,npm规定要使用一个叫 ...

  5. AutoMapper的介绍与使用(一)

    软件环境 vs2015 asp.net mvc 5 .NET Framework 4.5.2 AutoMapper 5.2.0.0 AutoMapper安装 新建asp.net mvc 项目 Auto ...

  6. 关系型数据库与NoSQL数据库

    关系型数据库的优缺点 优点: 可以做事务处理,从而保证了数据的一致性: 可以进行JOIN等多表查询: 由于以SQL标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处). 缺点: 大量数据的写 ...

  7. OpenGL: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  8. C++右值引用浅析

    一直想试着把自己理解和学习到的右值引用相关的技术细节整理并分享出来,希望能够对感兴趣的朋友提供帮助. 右值引用是C++11标准中新增的一个特性.右值引用允许程序员可以忽略逻辑上不需要的拷贝:而且还可以 ...

  9. 2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>

    前一阵子由于个人生活原因,具体见上一篇,耽搁了一阵子,在这里也十分感谢大家支持和鼓励.现在开始继续做WPF2000系列. 在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件 ...

  10. Spring集成MyBatis

    本文原创,原文地址为http://www.cnblogs.com/fengzheng/p/5045105.html 如果觉得Hibernate不够灵活,可以尝试用Mybatis.相比于Hibernat ...