python-55: 验证码的生成机制

前面的尝试失败了,为何呢?程序员

你们能够看到,咱们使用了两次urlopen,第一次是打开登录界面的网址获取验证码的地址,第二次是post数据到指定的网址,咱们虽然获取到了验证码,可是这实际上是一个很虚的事情,为何这么说呢?后端

仍是先看前面说的两个网址,api

  1. http://id.ifeng.com/allsite/login 这是登录界面的网址,用来显示输入界面和接受登录结果的信息
    浏览器

  2. https://id.ifeng.com/api/sitelogin 这是post数据的网址,js脚本,用来向服务器发送数据安全

咱们从登录界面获取验证码图片,而后向post数据的网址发送data,那么,咱们怎么能肯定这个过程当中验证码有没有改变呢?咱们的程序只进行了获取验证码,输入验证吗,post的操做,可是实际上,这中间具体通过了什么样的一个过程咱们并不知道,有可能咱们第二次使用urlopen来post数据的时候,这个验证码已经改变了呢?若是真的是这样,那咱们的代码获取的永远不是最新的验证码,这怎么可能登录得上呢?服务器

那么,应该怎么知道获取的验证码是否是最新的,或者,有没有什么方法可以保证post数据里面的验证码跟咱们网页获取到的是同一个验证码,但同时,我还发现了一个问题
cookie

https://id.ifeng.com/public/authcode 这个是咱们前面使用RE抽取出来的验证码的图片,我以为这个网址跟我想象中的不同,验证码不是每次刷新都不同的吗?为何这里就是是一个网址,甚至连什么序号之类的都没有?这不科学session

为了找出缘由我又从新运行了几回代码,发现仍是这个网址,可是点击进去以后图片已经变化了,我又把这个网址输入到浏览器的地址栏,不断的刷新,结果随着我不断的刷新,验证码的图片不断的改变,我很好奇为何会是这种状况,因而我请教了一些作网页设计的朋友post

验证码是什么前面实现那已经说了,那么如今来讲说验证码是怎么生成的
学习

咱们就拿相似于凤凰网的验证码来讲吧,在用户点击登录界面的时候,程序会自动生成一个随机数,并同时将这个随机数保存到session或者cookies中,生成一个id,以key-values的形式存放,而后经过必定的方法将这些数字或者字母进行处理,好比,扭曲,位置变换等等,最后生成一张图片并显示出来,用户输入后按key来寻找并对比用户输入的数值和随机数生成的数值是否相同

验证码机制是怎么实现

目前主流的实现技术主要有session和cookie两种方式,而这两种方式能够说技术是同样的,区别在于将验证码字符串存储在服务器仍是客户端。
前者工做流程:服务器发送验证码图片到客户端并在服务器保存验证码字符串到session,用户辨认图片并提交验证码字符串到服务器,服务器将用户提交的验证码字符串与session中保存的字符串进行比较。
后者工做流程:服务器发送验证码图片以及验证码字符串(可能会进行加密)到客户端,客户端将验证码字符串存储到本地cookie,用户辨认图片并提交验证码字符串以及cookie中所存储的字符串到服务器,服务器将用户提交的两个字符串(进行解密后)进行比较。
相对而言,存放在服务器的session更为安全,只不过消耗服务器内存,程序员除了使用模式识别辨认出验证码,没有其余办法。而对于使用cookie方式的验证码,不增长服务器内存消耗,但咱们能够经过对传输数据进行分析轻易破解验证码。

关于cookies和session的更加详细的信息能够到这个网站学习:http://blog.csdn.net/fangaoxin/article/details/6952954

通常来讲,为了安全起见,注册、登录等这些的验证码都是存放在服务器上的,也就是说,大部分是使用session的形式来实现的,若是能找到session-id或者是key,就有办法获得验证码的数据,可是session不是存放在服务器中吗?咱们怎么能获取获得呢?

实际上,session是后端的数据,咱们并不知道网站设计者在编写代码的时候是怎么设计的,或者作了什么限制,总之咱们很难获取获得,经过程序不能获取,甚至浏览器也不能获取,那应该怎么办呢?

cookies,咱们知道,浏览器向服务器发送请求,服务器响应并返回数据,固然,这些数据中也包含cookies,用户输入用户名和密码而后登录网站,若是登录成功,服务器会将一些信息写入cookies用于下次打开网页的时候自动登录,若是登录不上,也会将相应的信息写入cookies,在下次发送请求打开网页的时候告诉服务器,这个用户尚未登录,须要登录,从这个角度上来讲,cookies表明了你的状态,已经登录,或者,未登陆

咱们来设想这样一种状况,当咱们打开登录界面的时候,会随机生成一个验证码(好比:1234),并将这个验证码的信息生成一个session,好比, {key = session-1, values = 1234},这个session的信息是存放在服务器上面的,它须要保密因此不但愿浏览器获取到它,那就不给浏览器这些数据,好,如今服务器将不包含有任何session信息的数据返回给浏览器,浏览器提交验证码上的数字来进行登录,乍一看这整个过程好像没有什么错误,可是,若是100我的同时进行登录呢?

100个登录请求就会生成100个session,若是按照前面的方式,100个浏览器同时提交验证码,那么服务器怎么知道哪一个浏览器对应的是哪一个session呢?

因此,最好的办法是在浏览器发出登录请求的时候,服务器为浏览器生成一个标识,好比,"这是浏览器a,它对应的是session-1",固然,这个标识是通过加密的,服务器将这个标识和验证码等数据返回给浏览器,浏览器提交验证码的时候要带上这个标识信息,说,"我是浏览器a,对应的是session-1,我提交的验证码数据是1234",而后服务器将这些信息进行比对,若是匹配就登录成功

这也就是cookies的原理,说了这么多,实际上就是想说明,既然cookies可以携带用户是否已经登录的信息,那么,它应该也能够携带验证码的信息,虽然不会直接告诉咱们验证码是什么,可是会告诉服务器,"我是浏览器a,我刚刚已经请求了一个验证码,对应的是session-1" 相似这样的信息

这也就是咱们前面的代码为何不能成功的缘由,咱们没有告诉服务器咱们发送的验证码对应的是哪一个session,这就意味着,咱们须要先获取cookies,这个cookies里面包含验证码的信息,而后咱们带着这个cookies去post数据

相关文章
相关标签/搜索