随手记_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 ...
随机推荐
- RPC 使用中的一些注意点
最近线上碰到一点小问题,分析其原因发现是出在对 RPC 使用上的一些细节掌握不够清晰导致.很多时候我们做业务开发会把 RPC 当作黑盒机制来使用,但若不对黑盒的工作原理有个基本掌握,也容易犯一些误用的 ...
- web前端基础知识
#HTML 什么是HTML,和他ML... 网页可以比作一个装修好了的,可以娶媳妇的房子. 房子分为:毛坯房,精装修 毛坯房的修建: 砖,瓦,水泥,石头,石子.... 精 ...
- mysql学习之 sql语句的技巧及优化
一.sql中使用正则表达式 select name,email from user where email Regexp "@163[.,]com$"; sql语句中使用Regex ...
- nginx+php的使用
原文来自:windows下配置nginx+php环境 按照他的步骤走,亲测可用! 但是这里他后面说的根目录可能有些人有点懵. 其实在设置的时候就设置了: 网站根目录就是www这个目录,如果没创建请自行 ...
- Android 6.0 权限知识学习笔记
最近在项目上因为6.0运行时权限吃了亏,发现之前对运行时权限的理解不足,决定回炉重造,重新学习一下Android Permission. 进入正题: Android权限 在Android系统中,权限分 ...
- JavaScript常见的五种数组去重的方式
▓▓▓▓▓▓ 大致介绍 JavaScript的数组去重问题在许多面试中都会遇到,现在做个总结 先来建立一个数组 var arr = [1,2,3,3,2,'我','我',34,'我的',NaN,NaN ...
- ASP.NET Core project.json imports 是什么意思?
示例代码: "frameworks": { "netcoreapp1.0.0": { "imports" : "portable- ...
- 使用SecureCRT连接虚拟机(ubuntu)配置记录
这种配置方法,可以非常方便的操作虚拟机里的Linux系统,且让VMware在后台运行,因为有时候我直接在虚拟机里操作会稍微卡顿,或者切换速度不理想,使用该方法亲测本机效果确实ok,特此记录. Secu ...
- 《LoadRunner12七天速成宝典》来了
看到自己的新书又要发行了,算算从09年第一本书开始,不知不觉已经是第四本书了(帮朋友合写的书不算),每次写完之后都会说太累了,不想再写了,但是却又次次反悔,吞下食言的苦果.如果非要说第四本书的感受,那 ...
- Log4net - 项目使用的一个简单Demo
参考页面: http://www.yuanjiaocheng.net/entity/entitytypes.html http://www.yuanjiaocheng.net/entity/entit ...