悲剧了,发现写完这篇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

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

  1. Session Timer机制分析

    Session Timer机制分析 功能介绍 会话初始化协议(SIP)并没有为所建立的会话定义存活机制.尽管用户代理可以通过会话特定的机制判断会话是否超时,但是代理服务器却做不到这点.如此一来,代理服 ...

  2. 分布式session共享机制分析

    使用配置: 1.在pom文件中引入spring-session的jar包 <!--springsession--><dependency><groupId>org. ...

  3. zookeeper session tracker机制分析

    说到zookeeper session管理 ,免不了要问 什么是session? session id/session是如何产生的? session 信息如何存储? 本文以session tracke ...

  4. Flask框架(三)—— 请求扩展、中间件、蓝图、session源码分析

    Flask框架(三)—— 请求扩展.中间件.蓝图.session源码分析 目录 请求扩展.中间件.蓝图.session源码分析 一.请求扩展 1.before_request 2.after_requ ...

  5. Tesseract-OCR牛刀小试:模拟请求时的验证码识别

    原文:http://yaohuiji.com/tag/tesseract%EF%BC%8Cocr%EF%BC%8C%E9%AA%8C%E8%AF%81%E7%A0%81/ 有个邪恶的需求,需要识别验证 ...

  6. 获取登录验证码失败及前后端不同域导致session丢失问题分析记录

    前言 前两周在把兄弟公司的几个服务部署到我们公司测试环境服务器的时候又遇到了不少问题,因为是前后端分离的项目,所以这次也同样遇到了跨域问题,解决方式也跟上一回的不一样,这里就再来分析记录一下. 登录验 ...

  7. c# JD快速搜索工具,2015分析JD搜索报文,模拟请求搜索数据,快速定位宝贝排行位置。

    分析JD搜索报文 搜索关键字 女装 第二页,分2次加载. rt=1&stop=1&click=&psort=&page=3http://search.jd.com/Se ...

  8. 【教程】手把手教你如何利用工具(IE9的F12)去分析模拟登陆网站(百度首页)的内部逻辑过程

    [前提] 想要实现使用某种语言,比如Python,C#等,去实现模拟登陆网站的话,首先要做的事情就是使用某种工具,去分析本身使用浏览器去登陆网页的时候,其内部的执行过程,内部逻辑. 此登陆的逻辑过程, ...

  9. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

随机推荐

  1. ios7开发者必知

    如果你想为iOS 设备开发app,你需要知道如何与软件交互,如何设计,你还要知道苹果独特的开发理念和开发工具.真正的能力还需要成功地从其他行业领域借鉴核心概念.最后把所有这些东西糅合进你的信息库中, ...

  2. sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    在使用Hibernate的J2EE项目中,莫名其妙出现如上错误,既不报错,也不运行不论什么输出測试代码,更不返回结果. 经过排查,在方法里面引用的实体类和其映射文件属性个数不一致. 改动一致后,即解决 ...

  3. bat文件无法双击运行

    问题: win7系统下新建txt文件,编辑脚本内容后,保存为test.bat.每次双击它,只会默认以txt格式打开它,而不是运行它. 解决: 1. 双击打开“我的电脑”,然后在“工具”下选择“文件夹选 ...

  4. 用EnableMenuItem不能使菜单变灰的原因

    为何不能Disable菜单项     问:我有一个工具button在WM_COMMAND消息是这样做的:         CMenu   *pMenu   =   GetMenu();     pMe ...

  5. hdu1520 (树形dp)

    hdu1520 http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意是给定一棵树,每个结点有一个价值,要我们选择任意个结点使得总价值最大,规则是如果父亲结 ...

  6. 设计模式 - 模板方法模式(template method pattern) JFrame 具体解释

    模板方法模式(template method pattern) JFrame 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(templ ...

  7. iOS Dev (55) 获得本年度、月、日本和其他信息

    iOS Dev (55) 获得本年度.月.日本和其他信息 作者:大锐哥 博客:http://prevention.iteye.com - NSDate *now = [NSDate date]; NS ...

  8. Naive Bayes Classification

    Maching Learning QQ群:2 请说明来自csdn 微信:soledede

  9. MIT 操作系统实验 MIT JOS lab2

    MIT JOS lab2 首先把内存分布理清楚,由/boot/main.c可知这里把kernel的img的ELF header读入到物理地址0x10000处 这里能够回想JOS lab1的一个小问.当 ...

  10. 在JAVA中使用LUA脚本记,javaj调用lua脚本的函数(转)

    最近在做一些奇怪的东西,需要Java应用能够接受用户提交的脚本并执行,网络部分我选择了NanoHTTPD提供基本的HTTP服务器支持,并在Java能承载的许多脚本语言中选择了很久,比如Rhino,Jy ...