从session实现机制分析模拟请求验证码的可行性(转)

悲剧了,发现写完这篇blog没有配上这个格调超高的标题。

 

1.0问题背景

现在要实现一个带验证码网站的的自动登陆功能。验证码识别过程不再这篇文章的讨论之中。(之后有篇文章我会详细的总结验证码的识别过程)。现在问题来了,怎么拿到你本次请求登陆页面的验证码图片?

2.0方案分析

现在有几种思路:

(1)请求登陆页面,截取验证码图片,类似截屏,seleinum,webbrower的DrawToBitmap()等。

(2)还是webbrower,将图片复制到剪切板在从剪切板中搞出来

  • HTMLControlRange rang = (IHTMLControlRange)body.createControlRange();
  • IHTMLControlElement imge;
  • imge = (IHTMLControlElement)img.DomElement;
  • rang.add(imge);
  • rang.execCommand("Copy", false, null);
  • Image image = Clipboard.GetImage();

(3)前两种都是用一种类似浏览器的软件帮我们完成登陆页面的请求,下面我们来深入的分析下请求登陆页面这个过程是什么样子的。第一次请求这个页面

 

 

在浏览器中我们看到的是这个页面,我们用fidder抓包发现,我们关系的请求只有两次。

 

 

所以,我们第三种思路也来了。那我们用webclient或httpwebrequset模拟这两次请求不就完事了?一次请求登陆页面,一次请求验证码,然后模拟表单提交,多简单的事!

 

悲剧 就发生在这:你模拟请求的验证码输入后总是不对,一大堆的人都说你对验证码发了二次请求,你获得的验证码是上一次的!!有的人一想,我靠,是这么回事啊,怪不得不行呢,这方法不行啊。

 

大家仔细想一想,我怎么对验证码发送二次请求了?老子一共模拟两次请求,一次请求登陆页面,一次请求验证码,就一次好吗!所以这种说法是错误的,我们从头来分析:

 

第一次是请求这个登陆页面,这是请求头

这是response头:

我们发现服务器向客户端写了一个cookie;之后我们讨论这个cookie的作用。

 

我们继续观察第二请求,该请求是怎么发出来的呢?我们现在都应该知道了,第一次请求服务器返回的是这个登陆页面的html代码,对吧,浏览器拿到这个html代码后它就要渲染了,就是在浏览器给我画这个漂亮的页面。

 

当它看到这串代码时 <img width="60" height="25" src='/cas/codeimage/>它就认为,这是一个图片啊,我赶紧去按图片地址去拿吧,晚了就玩了,这样,他就发送了第二个请求。我们来看报文:

 

 

发现了什么,请求报文中竟然带了cookie。这就要涉及到cookie的工作原理了,cookie是写在客户端的,就是一个键值对,就是是写在你浏览器对应的cookie存放位置,cookie是不能跨浏览器的,360浏览器的cookie你google浏览器是不能玩的。

 

cookie是不能跨域的,就是不能a.com的cookie不能提交到c.com.而且cookie在同一域名下,会自动提交的,这也说明了第二次请求为什么会无缘无故的多了个cookie。cookie的作用path,过期时间等其他参数这里就不说了。

 

 

好了,关键的东西我们都发现了,就是这个cookie搞的。它到底是什么鬼?是干啥的?我们来分析下验证码的实现机制,不是讲怎么画出来的,用户去请求验证码,服务器生成验证码字符,然后把他存在session里,另外又把这个字符串画到图片上返回给浏览器。有人问session又是什么鬼?session也是一个键值对,跟cookie不同的是,session是存在服务器端的。服务器端有个session池,里面放的就是一个一个的键值对。

 

我们填完了验证码,提交到服务器,服务器开始判断你填的对不对,他怎么判断的呢?逗比,服务器不是有session吗?一比不就得了嘛!怎么比?服务器的session多了去了,所以只能拿着键,去找值,那这个值和你提交过来的值比。那么问题来了,键是那来的?你什么时候提交过来的?见鬼了?相信大家都已经想到了,这个键就是刚才那个cookie的值。

 

这样大家也就明白了,原来session是通过cookie实现的啊,你以为呢?

 

 

到这里,我们就找到第二次模拟请求验证码过程发生的问题了。原来是这次请求没有带上第一次请给的cookie。你没带,说明你提交的键是null,服务器却是真实有的,当然每次请求都错误 了。

 

知道错误地点了,这问题也就解决了:提交的时候直接带上第一次的cookie不就结了。简单代码:

CookieContainer cookiesContainer = new CookieContainer();

if (response1.Cookies.Count > 0)

{

cookiesContainer.Add(response1.Cookies);

}

 

requst2.CookieContainer =cookieContainer;

 

3.0总结

这里要说明下,这个cookie是到底什么时候给你写到客户端?按道理来讲,这个cookie这与你的验证码有关,你访问验证码图片时候,给你写个才对。但这个实验网站他访问登陆页面就给你写了,到你访问验证码页面时候,估计是他先判断你有没有写cookie,没写的话给你写上。所以这cookie在哪还得自己抓包看。另外还有很多隐藏域的值参与验证,分析的时候也要注意。

 

这还有个问题:服务器设定验证码session的时候,键直接设置为"VCde",还用从cookie里找干嘛?针对一个用户来说,这样是可以的,如果多个用户同时访问的话,会发生什么情况。A刚拿到验证码,VCde存的是A的字符。这时候B来登陆,VCde立马变成B的字符,A兴致勃勃的填完了去登陆,验证码错误!所以,cookie中村的不是vcode的key,他是sessionId,服务器中是session空间像一个柜子,sessionid就是那个柜子的钥匙,而柜子里存的才是你网session中存的数据,当然了,验证码就存在柜子里。

 

http://www.cnblogs.com/cnduan/p/4344097.html

时间: 2024-10-01 22:02:27

从session实现机制分析模拟请求验证码的可行性(转)的相关文章

asp.net中Session锁机制,第一次请求无效的问题

问题描述 第一次在CSDN上提问,请大牛们多关照啊背景描述:asp.net中,同一个会话(相同的SessionID)的不同请求,会由于Session锁机制产生阻塞问题,即如果两个请求都要修改Session的值,那么后到的请求要等前面的请求结束(锁释放)后才能访问到Session.但今天我发现了一个问题,首先贴测试代码:publicActionResultAbout(){Session["test"]="AboutMsg";ViewBag.Message=Sessio

PHP的SESSION机制分析

本篇文章主要介绍一下php session技术方面的文章. 1.session.save_handler = files 1. session_start() (1)session_start()是session机制的开始,它有一定概率开启垃圾回收,因为session是存放在文件中,PHP自身的垃圾回收是无效的,SESSION的回收是要删文件的,这个概率是根据php.ini的配置决定的,但是有的系统是 session.gc_probability = 0,这也就是说概率是0,而是通过cron脚本

httpwebrequest-HttpWebRequet模拟请求与浏览器一样,为什么Respnse回来的结果不一样?

问题描述 HttpWebRequet模拟请求与浏览器一样,为什么Respnse回来的结果不一样? 各位大牛, 小弟业余爱好者.我用HttpWebRequest模拟请求网站,我通过,Fiddler查看 我与浏览器的请求头Header,内容一样,但返回的结果不一样,我的程序得到的 是空白内容,而浏览器返回的是真正的内容.我研究,并提取了cookie,重新加 入请求头再次请求,结果还是空,到底是什么原因啊.请求各位高人,指点迷津. 解决方案 换个网站试试呢,所有网站都一样吗? 解决方案二: 除了coo

htmlunit 登录问题-htmlunit模拟登录 验证码错误

问题描述 htmlunit模拟登录 验证码错误 使用htmlunit模拟登录的时候 ,首先穿创建了一个webclient 用webclient请求登录页面,同事请求解析验证码,验证码解析正确,然后开始登录系统,一直提示验证码错误. WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_11); webClient.getOptions().setJavaScriptEnabled(true); webClient

Open vSwitch(OvS)源代码之Linux RCU锁机制分析

Open vSwitch(OvS)源代码之Linux RCU锁机制分析 前言 本来想继续顺着数据包的处理流程分析upcall调用的,但是发现在分析upcall调用时必须先了解linux中内核和用户空间通信接口Netlink机制,所以就一直耽搁了对upcall的分析.如果对Open vSwitch有些了解的话,你会发现其实Open vSwitch是在linux系统上运行的,因为Open vSwitch中有很多的机制,模块等都是直接调用linux内核的.比如:现在要分析的RCU锁机制.upcall调

php中session过期时间设置及session回收机制介绍_php技巧

网上很多人给出了解答:修改配置文件中的session.gc_maxlifetime.如果想了解更多session回收机制,继续阅读.(本文环境php5.2) 概述:每一次php请求,会有1/100的概率(默认值)触发"session回收".如果"session回收"发生,那就会检查/tmp/sess_*的文件,如果最后的修改时间到现在超过了1440秒(gc_maxlifetime的值),就将其删除,意味着这些session过期失效. 1. session在端(一般是

CodeIgniter配置之SESSION用法实例分析_php实例

本文实例讲述了CodeIgniter配置之SESSION用法.分享给大家供大家参考,具体如下: 刚使用Codeigniter时也被其中的SESSION迷惑过,后来就再也没用过CI自带的SESSION,想必还是有必要整理一下SESSION.为弄清CI中的SESSION,先来说一下PHP中SESSION是如何工作的.由于HTTP协议本身是无状态的,所以当保留某个用户的访问状态信息时,需要客户端有一个唯一标识传给服务端,这个唯一标识就是SESSION ID,存放在客户端的COOKIE中,然后服务端根据

大叔也说Xamarin~Android篇~为HttpClient共享Session,android与api的session共享机制

杂谈 在进行android进行开发时,我们的数据一般通过接口来获收,这里指的接口泛指web api,webservice,wcf,web应用程序等:它们做为服务端与数据库进行直接通讯,而APP这块通过向这些接口发Http请求来获得数据,这样的好处大叔认为,可以有效的降低软件的开发难度,所以数据交互都被分离到了服务层而,而与客户交互的功能完全都在APP端,这类似于目前比较流行的SOA架构,即一个服务为多种终端服务:无论是你WEB网站,手机IOS,手机Android,平板还是其它TV之类的,都统一调

Android开发:内存机制分析——堆和栈

  1.dalvik的Heap和Stack 这里说的只是dalvik java部分的内存,实际上除了dalvik部分,还有native.这个以后再说. 开发:内存机制分析--堆和栈-"> 下面针对上面列出的数据类型进行说明,只有了解了我们申请的数据在哪里,才能更好掌控我们自己的程序. 2.对象实例数据 实际上是保存对象实例的属性,属性的类型和对象本身的类型标记等,但是不保存实例的方法.实例的方法是属于数据指令,是保存在Stack里面,也就是上面表格里面的类方法. 对象实例在Heap中分配好