随手记_C#验证码
前言
最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果:
总体来说效果还是可以的,官方提供的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>
<!-- 请输入验证码-->
<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#验证码的更多相关文章
- .net点选验证码实现思路分享
哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个. 先上效果图 如果你被这个效果吸引了就请继续看下去. 贴代码前先说点思路: 1.要有一个汉字库,并按字形分类.(我在数据库里是安部首分类 ...
- 【探索】无形验证码 —— PoW 算力验证
先来思考一个问题:如何写一个能消耗对方时间的程序? 消耗时间还不简单,休眠一下就可以了: Sleep(1000) 这确实消耗了时间,但并没有消耗 CPU.如果对方开了变速齿轮,这瞬间就能完成. 不过要 ...
- TODO:Laravel增加验证码
TODO:Laravel增加验证码1. 先聊聊验证码是什么,有什么作用?验证码(CAPTCHA)是"Completely Automated Public Turing test to te ...
- PHP-解析验证码类--学习笔记
1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1 定义变量 //随机因子 private $char ...
- WPF做12306验证码点击效果
一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...
- 零OCR基础6行代码实现C#验证码识别
这两天因为工作需要,要到某个网站采集信息,一是要模拟登陆,二是要破解验证码,本想用第三方付费打码,但是想想网上免费的代码也挺多的,于是乎准备从网上撸点代码下来,谁知道,撸了好多个都不行,本人以前也没接 ...
- ASP.NET中画图形验证码
context.Response.ContentType = "image/jpeg"; //生成随机的中文验证码 string yzm = "人口手大小多少上中下男女天 ...
- asp.net mvc 验证码
效果图 验证码类 namespace QJW.VerifyCode { //用法: //public FileContentResult CreateValidate() //{ // Validat ...
- ecshop验证码
<?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...
随机推荐
- C#与C++的发展历程第三 - C#5.0异步编程巅峰
系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 3. C#与C++的发展历程第三 - C#5.0异步编程的巅峰 C#5.0 ...
- Python高手之路【一】初识python
Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...
- ABP文档 - SignalR 集成
文档目录 本节内容: 简介 安装 服务端 客户端 连接确立 内置功能 通知 在线客户端 帕斯卡 vs 骆峰式 你的SignalR代码 简介 使用Abp.Web.SignalR nuget包,使基于应用 ...
- Spark RDD 核心总结
摘要: 1.RDD的五大属性 1.1 partitions(分区) 1.2 partitioner(分区方法) 1.3 dependencies(依赖关系) 1.4 compute(获取分区迭代列表) ...
- Yii1.1的验证规则
在Yii1.1的数据验证是由CValidator完成,在CValidator中提供了各种基本的验证规则 <?php public static $builtInValidators=array( ...
- MVC5 网站开发之九 网站设置
网站配置一般用来保存网站的一些设置,写在配置文件中比写在数据库中要合适一下,因为配置文件本身带有缓存,随网站启动读入缓存中,速度更快,而保存在数据库中要单独为一条记录创建一个表,结构不够清晰,而且读写 ...
- 有趣的 CSS 像素艺术
原文地址:https://css-tricks.com/fun-times-css-pixel-art/#article-header-id-4 译者:nzbin 友情提示:由于国内网络的原因,Cod ...
- jQuery学习之路(8)- 表单验证插件-Validation
▓▓▓▓▓▓ 大致介绍 jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 ...
- 代码的坏味道(21)——中间人(Middle Man)
坏味道--中间人(Middle Man) 特征 如果一个类的作用仅仅是指向另一个类的委托,为什么要存在呢? 问题原因 对象的基本特征之一就是封装:对外部世界隐藏其内部细节.封装往往伴随委托.但是人们可 ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...