我在上一篇文章中已经讲解了一般网站的登录原来和C#的登录实现,很多人问到对于使用了验证码的网站该怎么办,这里我就讲讲验证码的原理和对应的登录方法。

验证码的由来

几年前,大部分网站、论坛之类的是没有验证码的,因为对于一般用户来说验证码只是增加了用户的操作,降低了用户的体验。但是后来各种灌水机器人、投票机器人、恶意注册机器人层出不穷,大大增加了网站的负担同时也给网站数据库带来了大量的垃圾数据。为了防止各种机器人程序的破坏,于是程序员想出了只有人眼能够识别的,程序不容易识别的验证码!

验证码是一个图片,将字母、数字甚至汉字作为图片的内容,这样一张图片中的内容用人眼很容易识别,而程序将无法识别。在进行数据库操作之前(比如登录验证、投票、发帖、回复、注册等等)程序首先验证客户端提交的验证码是否与图片中的内容相同,如果相同则进行数据库操作,不同则提示验证码错误,不进行数据库操作。这样各种机器人程序就被拒之门外了!

但是随着计算机科学的发展,模式识别等技术越来越成熟,于是编写机器人程序的家伙可以通过程序将直接写在图片中的内容识别出来,然后提交到服务器,这样验证码将形同虚设。为了防止机器人程序的识别,验证码的图片生成也不断在发展,加入干扰点、干扰线,文字变形、变换角度位置,颜色不同……各种防止计算机识别的技术也应用到验证码中。就在这两种技术的竞争中,于是便形成了我们现在看到的验证码,已经有很多人在抱怨“这是什么验证码哦,人眼都分辨不清楚是什么”,一切也是无奈。

验证码的使用

验证码是针对各种机器人程序的,所以验证码图片中的内容是不能存放在Cookie、HTML和URL中的,如果看到一个验证码图片的URL是http://xxxxxx.com/Expwd.aspx?code=1af8 而验证码图片中的内容就是1af8那将是十分可笑的事情。同时,如果通过抓包发现了Cookie中保存了验证码的值或者查看HTML时看到了形如:<input type="hidden" id="exPwd" name="exPwd" value="1af8"/>这样将验证码的内容放在隐藏元素中也是不可思议的。对于这些行为,显然是这个程序员不知道验证码是拿来干什么的,只是别人的网站上有验证码,与自己的网站也弄一个来赶时髦。另外还有一种好笑的是验证码看上去像是验证码,结果看HTML代码居然不是一个图片,而是一个<span>1</span><span>a</span><span>f</span><span>8</span>。大家不要不以为然,以上这几种情况还真是我现实生活中遇到过的,当年写投票机器人的时候遇到这种情况我最高兴了!!!

验证码的内容必须保存在服务器端,一般我们可以将随机生成的验证码的内容放入Session中,用户提交的时候将提交的内容与Session中的验证码进行比较判断。在生成验证码的页面后台代码可以写为:

protected void Page_Load(object sender, EventArgs e)
   {
string checkCode = CreateCode(4);
       Session["CheckCode"] = checkCode;
       CreateImage(checkCode);
   }

比如在登录进行验证的时候可以写为:

protected void btnLogin_Click(object sender, ImageClickEventArgs e)
  {
if (Session["CheckCode"] == null)
      {
          UIHelper.Alert(Page, "验证码已过期,请重新输入");
return;
      }
if (Session["CheckCode"].ToString().ToLower() != txbCode.Text.ToLower())//验证码忽略大小写
      {
          UIHelper.Alert(Page, "验证码错误");
return;
      } 
//数据库验证…… 
}

使用C#登录带验证码的网站

前面我们已经对整个验证码的原理和使用有了基本的了解,现在言归正传,讲讲如何登录带验证码的网站。这里我们以CSDN的登录为例。

1.在IE中正常登录一次并把登录时候的数据包抓下来。

2.分析其中的登录原理如下:

1)请求http://passport.csdn.net/UserLogin.aspx页面,与服务器建立会话,服务器返回一个SessionID在HTTP的Header中,如下,其他内容我们可以忽略。

ASP.NET_SessionId=ydebagnqgiiixi2dvihfw355; path=/; HttpOnly,ABCDEF=; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,QWERTOP=; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,activeUserName=Guest; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,UserName=Guest; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,PName=; domain=csdn.net; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,ClientKey=; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,userid=0; expires=Tue, 22-Apr-2008 17:57:01 GMT; path=/,ClientKey=933ffb09-5096-4fbb-b90f-5f0bff335b41; path=/

2)该页面返回的HTML中有一个<input type="hidden" name="ClientKey" value="a50b14fa-2a75-4364-bbeb-3b498b72aa46" />这个值在登录提交时也需要,所以需要从HTML代码中分离出来。

3)将该SessionID作为Cookie的内容发送到验证码生成的页面http://passport.csdn.net/ShowExPwd.aspx 该页面将返回一个图片的二进制流。

4)将返回的二进制流转换为图片并呈现给用户。

Image img = new Bitmap(
          Http.GetStreamByBytes("http://passport.csdn.net" , "http://passport.csdn.net/ShowExPwd.aspx", b,
                                aspcookie, out header));//获得验证码图片
this.pictureBox1.Image = img;

5)用户输入用户名、密码和验证码,然后和同前面分离出的ClientKey按如下的格式POST到http://passport.csdn.net/UserLogin.aspx进行验证。

__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE4NDgzMDI2NjcPFgIeCkZpbmlzaFN0YXloFgJmD2QWBAIBDxYCHgRUZXh0BQznlKjmiLfnmbvlvZVkAgIPZBYCAgMPZBYCAgEPFgIeB1Zpc2libGVoZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAgUeY3RsMDAkQ1BIX0NvbnRlbnQkY2JfU2F2ZVN0YXRlBR1jdGwwMCRDUEhfQ29udGVudCRJbWFnZV9Mb2dpbr5SL%2FGtMqVCJ%2FCh4jH%2FXp4DhlVU&ctl00%24CPH_Content%24tb_LoginNameOrLoginEmail=studyzy&ctl00%24CPH_Content%24tb_Password=123&ctl00%24CPH_Content%24tb_ExPwd=wgssj&ClientKey=a50b14fa-2a75-4364-bbeb-3b498b72aa46&ctl00%24CPH_Content%24cb_SaveState=on&from=http%3A%2F%2Fhi.csdn.net%2Fmy.html&MailParameters=&MailParameters=&ctl00%24CPH_Content%24Image_Login.x=26&ctl00%24CPH_Content%24Image_Login.y=11

6)验证成功的话将返回包含用户信息(发帖数、积分、博客排名等等)的HTML,验证失败将返回具体的错误信息。

3.以上将CSDN的登录原理分析清楚了,那么接下来就是代码实现了,代码实现比较简单,我直接在上篇文章所使用的Demo代码上修改的,所以写的不是很漂亮,大家若有兴趣可以看看。/Files/studyzy/LoginCSDNDemo.rar
成功登录后如图:

现在当前用户已经成功登录了,那么接下来是要在CSDN上发表博客、论坛发帖只需要将当前的SessionID放入Cookie中,在提交时使用该Cookie即可。

使用C#登录带验证码的网站相关推荐

  1. 使用PKav HTTP Fuzzer 爆破带验证码的网站

    首先需要下载PKav HTTP Fuzzer ,地址如下: 链接:https://pan.baidu.com/s/1Ddwcg7CW09hhyEUSugjENg 提取码:fypx 这个PKav HTT ...

  2. python爬虫登录有验证码_大神教你用Python爬虫模拟登录带验证码网站

    爬取网站时经常会遇到需要登录的问题,这是就需要用到模拟登录的相关方法.python提供了强大的url库,想做到这个并不难.这里以登录学校教务系统为例,做一个简单的例子. 首先得明白cookie的作用, ...

  3. python 网站发送验证码_Python爬虫模拟登录带验证码网站

    爬取网站时经常会遇到需要登录的问题,这是就需要用到模拟登录的相关方法.python提供了强大的url库,想做到这个并不难.这里以登录学校教务系统为例,做一个简单的例子. 首先得明白cookie的作用, ...

  4. 基于HttpClient的正方教务系统模拟登录(带验证码)

    PS:恩,由于最近在学web和简单的http协议,所以心血来潮想用java写个爬虫来爬取学校官网(正方教务系统)个人主页的基础信息(课程信息.成绩--),其实在之前学过java基础教程的时候就可以写的 ...

  5. Android模拟登陆带验证码的网站客户端

    首先获取验证码并保存Cookie,登陆时将Cookie和账号密码一同发送出去,返回状态码200,登陆成功,接下来再去访问其他需要登录权限的页面时附上Cookie发送出去即可. 要实现模拟登陆,首先需要 ...

  6. 途牛旅游项目--登录带验证码

    学习目标 (1)改进登录 (2)注册功能 MySessionUtils改进 (1) A依赖B,移除B,A报错,耦合 com\wzx\util\MySessionUtils2.java public s ...

  7. python 登陆网站图片验证,用python登录带弱图片验证码的网站

    上一篇介绍了使用python模拟登陆网站,但是登陆的网站都是直接输入账号及密码进行登陆,现在很多网站为了加强用户安全性和提高反爬虫机制都会有包括字符.图片.手机验证等等各式各样的验证码.图片验证码就是 ...

  8. python实现网站的自动登录(selenium实现,带验证码识别)

    python实现网站自动登录(selenium实现,带验证码识别) 一.前言 这是鄙人写的第一篇博客,旨在总结一下近期所学,本文通过selenium工具实现工作所用网站的自动登录,下图为网站登录界面. ...

  9. 登录页面html5 css3 js代码,H5+css3+js搭建带验证码的登录页面

    本文实例为大家分享了H5+css3+js搭建带验证码的登录页面,供大家参考,具体内容如下 login.html EasyBuy后台管理系统 .main_bar{ width:1350px; heigh ...

最新文章

  1. 本地文件与服务器传输,云服务器 与本地文件传输
  2. javascript 中的eval方法 小窍门
  3. 文巾解题 45. 跳跃游戏 II
  4. 约会用语(很经典的)
  5. 【机器学习】SVM线性可分
  6. 虚拟化精华问答 | 如何为虚拟机分配任务?
  7. Filebeat 收集日志的那些事儿
  8. php把二维数组变为一维,如何将PHP二维数组转换为一维数组
  9. 解决svn中“工作副本已经锁定”,或者svn清理失败的解决方法
  10. 手机付费未成规模 阅读市场付费意愿萎缩
  11. mysql查询表字段默认值
  12. Wonderware- Intouch 利用 Excel 控件制作报表,功能强大
  13. dnf时装补丁教程_【时装补丁制作】消灭伸手党!最详细的图文教程~
  14. 中文字符集与字符编码的基础知识
  15. 拉普拉斯变换 性质 及常用函数变换
  16. 初探 ModBus4j -简单使用指南
  17. java实现支付宝二维码支付(Spring Boot)
  18. Cilium 开源 Tetragon – 基于 eBPF 的安全可观测性 运行时增强
  19. p5.js实现细胞免疫动画
  20. iOS 10适配须知

热门文章

  1. 信息学奥赛一本通(1194:移动路线)
  2. 信息学奥赛一本通(1108:向量点积计算)
  3. 拦截导弹(信息学奥赛一本通-T1260)
  4. 计算多项式的值(信息学奥赛一本通-T1093)
  5. 23 CO配置-控制-产品成本控制-成本对象控制-检查定单类型
  6. python规定浮点数类型可以不带小数部分吗_Python标准数据类型-数字
  7. 数组中查找並返回数组_剑指 Offer 04. 二维数组中的查找
  8. JAVA岗位比嵌入式岗位_java嵌入式职业选择?
  9. pyinstaller打包的文件运行失败:numpy.core.multiarray failed to import
  10. 记录几个CentOS安装包(rpm)的下载地址-离线安装必备