验证码 Captcha 之大插件小用

不知何年何月才能完成OADemo啊,总之还是一步一步来吧,这段时间开始着手了,先做登陆。  前段时间研究了一下在CentOS7下安装Mysql和Memcached服务,并测试了用C#操作,结果还行。

今天做一个简单的基于Bootstarp的响应式登陆页面(其实是在网上下的模板),不管是登陆还是注册吧,都会用到验证码,以前是用GDI绘出来的,觉得太丑了,百度的关于.net的验证码绝大多数也是用的这种方法,最后试了一下captcha,觉得还挺好看的,所以就试着用用。

nugit控制台install-package captcha到项目就行了,下载好了有个readme.txt文件,照着搞了一下,挺方便的

后台代码这样写的

[HttpPost]
[CaptchaValidation("CaCode", "ExampleCaptcha", "Incorrect CAPTCHA code!")]
public ActionResult ExampleAction(bool captchaValid)
{ if (!captchaValid)
{
return Content("no");
}
else
{
return Content("ok");
}
}

前台这样子的

<form action="/Example/ExampleAction" method="post">
@{
MvcCaptcha exampleCaptcha = new MvcCaptcha("ExampleCaptcha");
exampleCaptcha.UserInputID = "CaCode";
exampleCaptcha.ImageStyle = BotDetect.ImageStyle.CaughtInTheNet2;
@Html.Captcha(exampleCaptcha)
@*@Html.TextBox("CaCode")*@
<input type="text" id="CaCode" name="CaCode"/>
}
<input type="submit" value="GO" />
</form>

这都是照着readme搞的,当然还有注册路由的

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*botdetect}", new { botdetect = @"(.*)BotDetectCaptcha\.ashx" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

就这三步就行了,然后测试一下,先输个错的试试,点GO,输出no,很好,再搞个对的,输出ok相当可以,再然后,不小心输错了还是ok,再然后空的还是ok???

把浏览器关了,重新生成再打开试,哪怕第一次是错的也是输出ok。另外还有一个问题点图片就会转到https://captcha.org/captcha.html?asp.net这个地址。

问题一

出现这个问题按理说应该是好事,说明插件帮我们做了缓存验证码的事,并且还设置了过期时间,将部分属性打印到页面看看情况

<form action="/Example/ExampleAction" method="post">
@{
MvcCaptcha exampleCaptcha = new MvcCaptcha("ExampleCaptcha");
exampleCaptcha.UserInputID = "CaCode";
exampleCaptcha.ImageStyle = BotDetect.ImageStyle.CaughtInTheNet2;
@Html.Captcha(exampleCaptcha)
@*@Html.TextBox("CaCode")*@
<input type="text" id="CaCode" name="CaCode"/>
<ul>
<li>HelpLinkUrl: @exampleCaptcha.HelpLinkUrl</li>
<li>AddInitScript: @exampleCaptcha.AddInitScript</li>
<li>AdditionalCssClasses: @exampleCaptcha.AdditionalCssClasses</li>
<li>AdditionalInlineCss: @exampleCaptcha.AdditionalInlineCss</li>
<li>AddScriptInclude: @exampleCaptcha.AddScriptInclude</li>
<li>AutoClearInput: @exampleCaptcha.AutoClearInput</li>
<li>AutoFocusInput: @exampleCaptcha.AutoFocusInput</li>
<li>AutoReloadTimeout: @exampleCaptcha.AutoReloadTimeout</li>
<li>CodeLength: @exampleCaptcha.CodeLength</li>
<li>CodeStyle: @exampleCaptcha.CodeStyle</li>
<li>CodeTimeout: @exampleCaptcha.CodeTimeout</li>
<li>HelpLinkEnabled: @exampleCaptcha.HelpLinkEnabled</li>
<li>HelpLinkText: @exampleCaptcha.HelpLinkText</li>
<li>IconsDivWidth: @exampleCaptcha.IconsDivWidth</li>
<li>ReloadIconUrl: @exampleCaptcha.ReloadIconUrl</li>
<li>SoundIconUrl: @exampleCaptcha.SoundIconUrl</li>
<li>ImageStyle: @exampleCaptcha.ImageStyle</li>
<li>Locale: @exampleCaptcha.Locale</li>
<li> @exampleCaptcha.HelpLinkMode</li>
<li> @exampleCaptcha.WebCaptcha.CaptchaImageUrl</li>
<li> @exampleCaptcha.WebCaptcha.CaptchaBase.GetCode("ExampleCaptcha", BotDetect.CodeGenerationPurpose.ImageGeneration).CaptchaCode</li>
</ul>
}
<input type="submit" value="GO" />
</form>

从第一个属性来看应该是解决问题二的办法,但是很不幸,设置exampleCaptcha.HelpLinkUrl和HelpLinkText的值无效,结果还是回到了默认值。

还有就是CodeTimeout也是设置无效。在webconfig中

<sessionState mode="InProc" cookieless="AutoDetect" timeout="20" sessionIDManagerType="BotDetect.Web.CustomSessionIdManager, BotDetect" />

设置timeout小于20的值也无效,可能是有个最小值限定吧,这里我还没有试过超过20的值,晕!

其它的还好吧。

最后一个属性是我企图找出当前的验证码,依然很不幸,并不是,到现在我还没办法得到。之所以想得当验证码,其一是我觉得它帮我做的就是在session中缓存了验证码,可我并不想用session,如果只是保存在cookie中,那敢情好,我也无需得到验证码。

看看点击刷新按钮的请求

可以看出有三个GET请求,前两个是请求刷新和声音的按钮,后面一个是请求图片的。主要看后面一个,看来是有请求cookie的,并且有两个key。虽然如此,可我还并不肯定到底有没有用session缓存,关于这个,希望路过的大牛给予指导

再看看参数,有四个参数,每次请求只有d的值是变化的,这就是跟我们以前用的验证码刷新是一个意思啦。这个请求地址正是exampleCaptcha.WebCaptcha.CaptchaImageUrl的属性值。

看看刷新按钮最终生成的html是什么样子的,如下图,最关键的是a标签的onclick(红框框起部分),虽然看不到具体方法,但能知道方法的最终结果就是为了完成上面的请求。能理解这个,其它的都可以理解了。

其二我并不喜欢在前端写过多的C#代码。观察了一下后端代码

[CaptchaValidation("CaCode", "ExampleCaptcha", "Incorrect CAPTCHA code!")]

public ActionResult ExampleAction(bool captchaValid)...

对于Action的参数captchaValid我很不解,当我改变参数名称后就会报错,想想应该是CaptchaValidationAttribute中得来的吧,觉得用这个Attribute限制太多,不够灵活。最终我去掉了Attribute,用MvcCaptcha类的静态方法 MvcCaptcha.Validate(string,string,string),这个重载需要三个参数一个是captcha的Id,一个是用户输入值,另一个是validtingInstanceId

对于最后一个参数我开始摸不着北,后面在html源码中找到个hidden的input,只是感觉像是它,因为它有name属性,凭着感觉试了,没想还真行

那么就把后台给改了试试,其实最后个参数的值就是exampleCaptcha.CurrentInstanceId这个属性值(有时我自己觉得我有点傻的可爱),这样一来问题一就解决了部分问题,可以不用在前端写那么多C#代码了,并且每次登陆页面都要输入对的验证码才能ok。

public ActionResult ExampleAction(string CaCode, string BDC_VCID_ExampleCaptcha)
{
string instaneId = CustomCaptcha.CurrentInstanceId;
bool captchaValid= MvcCaptcha.Validate("ExampleCaptcha", CaCode,BDC_VCID_ExampleCaptcha);
if (captchaValid)
return Content("ok");
return Content("no");
}

问题二

解决问题二我用的办法很粗暴,我后来重做了一个MVC项目,做了一个完整的登陆页面,那个刷新和声音按钮我不好布局,直接给隐藏了,既然它粗暴的让改属性值不能改变验证图片的点击链接,我又不能说让用户点图片进入一个外国网站,那么我也只能粗暴通过jquery来解决问题,我想的办法就是把前面关于刷新按钮的a标签的onclick给图片中a标签的onclick,简单粗暴。

虽然两个问题并没有完美解决,但感觉自己还在挺努力的。所以最后把修改的全部代码贴上吧

最终效果

前端

后端专门写了一个类,有一个静态属性,用于指定当前验证码的实例Id,一个静态方法,用于自定义captcha

using BotDetect.Web.Mvc;

namespace OADemo.MVCApp
{
public class CustomCaptcha
{
/// <summary>
/// 当前验证码的实例Id
/// </summary>
public static string CurrentInstanceId { get { return currentInstanceId; } }
private static string currentInstanceId;
public static MvcCaptcha GetCaptcha(string captchaId)
{
MvcCaptcha exampleCaptcha = new MvcCaptcha(captchaId);
exampleCaptcha.ImageStyle = BotDetect.ImageStyle.CaughtInTheNet2;
exampleCaptcha.ReloadEnabled = false;
exampleCaptcha.SoundEnabled = false;
currentInstanceId = exampleCaptcha.CurrentInstanceId;
return exampleCaptcha;
}
/// <summary>
/// 获取自定义的验证码样式
/// </summary>
/// <param name="captchaId"></param>
/// <param name="width">指定验证码图片的宽度</param>
/// <param name="height">指定验证码图片的高度</param>
/// <param name="codeLength">指定验证码的个数</param>
/// <returns></returns>
public static MvcCaptcha GetCaptcha(string captchaId,int width,int height,int codeLength)
{
MvcCaptcha exampleCaptcha = new MvcCaptcha(captchaId);
exampleCaptcha.ImageStyle = BotDetect.ImageStyle.CaughtInTheNet2;//我个人喜欢的风格
exampleCaptcha.ReloadEnabled = false;//去掉刷新的按钮
exampleCaptcha.SoundEnabled = false;//去掉声音播放按钮
exampleCaptcha.CodeLength = codeLength;//指定验证码的长度
exampleCaptcha.ImageSize = new System.Drawing.Size(width,height);//指定图片的大小
currentInstanceId = exampleCaptcha.CurrentInstanceId;//当前实例的id
return exampleCaptcha;
}
}
}

后端控制器代码

Controller Code

好吧,后端控制器代码应该是这样才对的

using System.Web.Mvc;

namespace OADemo.MVCApp.Controllers
{
public class LoginController : Controller
{ // GET: Login
public ActionResult Index()
{
return View();
}
public ActionResult Account(string CaptchaCode, string username, string password)
{
string instaneId = CustomCaptcha.CurrentInstanceId;
bool captchaValid= MvcCaptcha.Validate("ExampleCaptcha", CaptchaCode,instaneId);
if (captchaValid)
return Content("ok");
return Content("no");
}
}
}

目前就写到这里了,当然后面的验证还没写,还只是在测试captcha阶段,所以想说要源码的同志,就不要费力了,因为这里忘记密码和注册都没有写的。这一篇完全只是写的我目前对captcha的研究,也许在众多的MvcCaptcha类的事件中,才是真正有效解决问题的办法,只是我没有英文水平,加上现在时间太晚,眼睛和脑袋受不了,暂告一段落,事件这么多呢,搞懂了,webconfig配置都可以自定义

 public static event EventHandler<GeneratedCaptchaCodeEventArgs> GeneratedCaptchaCode;
public static event EventHandler<GeneratedCaptchaImageEventArgs> GeneratedCaptchaImage;
public static event EventHandler<GeneratedCaptchaSoundEventArgs> GeneratedCaptchaSound;
public static event EventHandler<GeneratingCaptchaCodeEventArgs> GeneratingCaptchaCode;
public static event EventHandler<GeneratingCaptchaImageEventArgs> GeneratingCaptchaImage;
public static event EventHandler<GeneratingCaptchaSoundEventArgs> GeneratingCaptchaSound;
public static event EventHandler<InitializedWebCaptchaEventArgs> InitializedWebCaptcha;
public static event EventHandler<ValidatedUserInputEventArgs> ValidatedUserInput;
public static event EventHandler<ValidatingUserInputEventArgs> ValidatingUserInput;

验证码 Captcha 之大插件的更多相关文章

  1. 一步一步实现MVC5+EF6+Bootstarp+Autofac+NoSql实现OADemo 之登陆(一) 验证码 Captcha 之大插件小用

    不知何年何月才能完成OADemo啊,总之还是一步一步来吧,这段时间开始着手了,先做登陆.  前段时间研究了一下在CentOS7下安装Mysql和Memcached服务,并测试了用C#操作,结果还行. ...

  2. linux下tomcat6无法显示图片验证码 少了图形插件

    linux下tomcat6无法显示图片验证码(windows下显示正常) 原创 2015年10月20日 10:31:47 3526 linux下tomcat6无法显示图片验证码(windows下显示正 ...

  3. laravel 5.5 登录验证码 captcha 引入

    https://blog.csdn.net/u013372487/article/details/79461730 前提: 开启Laravel 的用户认证功能 1.安装 Captcha 安装 Capt ...

  4. Typecho中文验证码Captcha插件

    前言实在是受不了每天都要删除掉上百条的垃圾评论,干脆自己做了个验证码插件,顺带做的完善了些,分享给大家. 本插件是在评论验证码插件基础上完善而来.所不同的是,采用了最新的securimage 3.0. ...

  5. 验证码(captcha)的由来

    如果您允许用户在您的网站上发表内容,如留下评论和创建用户配置文件,那么您可能会看到,垃圾留言散播者试图利用这些渠道来给他们自己的网站创造流量.在您的网站上出现这类垃圾留言,对任何人来说都不愉快.用户可 ...

  6. django验证码captcha

    官方文档 https://django-simple-captcha.readthedocs.io/en/latest/usage.html#installation 使用命令安装pip instal ...

  7. vscode-常用插件介绍(10大插件)

    https://www.cnblogs.com/zhaoshujie/p/9834654.html 本文介绍了目前前端开发最受欢迎的开发工具 VSCode 必装的 10 个开发插件,用于大大提高软件开 ...

  8. java验证码Captcha

    import java.awt.Color; import java.io.IOException; import java.util.Random; import javax.servlet.htt ...

  9. captcha.js一个生成验证码的插件,使用js和canvas生成

    一.captcha`captcha.js`是一个生成验证码的插件,使用js和canvas生成的,确保后端服务被暴力攻击,简单判断人机以及系统的安全性,体积小,功能多,支持配置. 验证码插件内容,包含1 ...

随机推荐

  1. Eclipse用法和技巧十九:eclipse修改workspace

    工作中某一个项目的文件一般都在某一个路径,大多数人都习惯固定eclipse的workspace.不过偶尔也有点别的,比如做一个大项目中穿插着做些OJ,或者别的……这个时候当然可以选择在安装一个ecli ...

  2. 在WPF的DATAGRID中快速点击出现在ADDNEW或EDITITEM事务过程不允许DEFERREFRESH

    原文 在WPF的DATAGRID中快速点击出现在ADDNEW或EDITITEM事务过程不允许DEFERREFRESH 在项目中关于DataGrid的遇到过一些问题,其中是关于迁入CheckBox的双向 ...

  3. 基于visual Studio2013解决C语言竞赛题之1049抓牌排序

       题目 解决代码及点评 /* 功能:插入排序.许多玩牌的人是以这样的方式来对他们手中的牌进行排序的: 设手中原有3张牌已排好序,抓1张新牌,若这张新牌的次序在原来的第2张牌之后,第 3 ...

  4. VC 对话框背景颜色、控件颜色

    系统环境:Windows 7软件环境:Visual C++ 2008 SP1本次目的:为对话框设置背景颜色.控件颜色 既然MFC对话框不好开发,那么现在我们来开始美化我们的对话框.为对话框设置背景颜色 ...

  5. hdu5338 ZZX and Permutations

    hdu5338 ZZX and Permutations 非原创,来自多校题解 不是自己写的,惭愧ing…… 留着以后自己参考…… lower_bound {1,2,4,5} 询问 2,返回的是 2 ...

  6. android怎样实现自动点击功能

    一个按钮之类的控件的自动点击的话,可以定时调用 button.performClick();

  7. HDU 1251 统计难题 (字符串-Trie树)

    统计难题 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单 ...

  8. Hadoop自定义Counter

    1.通过enum自定义Counter public static num LOG_PROCESSOR_COUNTER { BAD_RECORDS }; 2.在Mapper或者Reducer中操作Cou ...

  9. 读书与写论文的引导书——leo鉴书60

    我是专科直接考的研究生.在论文写作方面基本能够算是初级.MBA毕业那会儿要写论文,在网上找了不少这方面的书,<论文与治学>是当中之中的一个. 这本那时为应景儿卖的书,成了我之后学习与工作的 ...

  10. 免插件打造wordpress投稿页面

    一.新建投稿页面模板 把主题的 page.php 另存为 tougao.php,并且在第一行的 <?php 之后添加模板的标识注释: /* Template Name: tougao */ 紧接 ...