Tornado框架实现图形验证码功能

Tornado框架实现图形验证码功能

 

    Tornado框架实现图形验证码功能

常在网上晃悠的人,对上面这个图片不陌生。特别是在注册、登录、发帖等等时候会频繁出现。那么它有什么作用,它的原理是什么呢?

 

什么是验证码?

      验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序

 

验证码的作用?

 

可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。

 

验证码自从2002年提出以来,证明了它的效果后,在互联网上得到了迅速的推广。在发展过程中,出现了图形验证码,语言验证码,邮件验证码,短信验证码等等。但是它们的原理大抵相同。

 

验证码原理!

      首先验证码是一个程序概念,它通过向请求的发起方提出问题,能正确回答的即使人类,反之则为机器。这个程序基于这个样一个重要的假设:提出的问题要容易被人类解答,机器无法解答。在当时的技术条件下,识别扭曲的图形,对于机器来说还是一个很艰难的任务,对于人来说,相对可以接受。所以最开始的验证码是图形验证码,也是比较容易实现的验证码。

 

图形验证码的工作流程

      我们登录,注册时首先会向服务器发送一个页面请求。服务器在接到这个请求后,随机生成一个字符串,然后将这个字符串画成一张图片,并将这个图片返回给请求用户。用户在收到这个页面之后再次提交请求数据时,需要识别这张图片上的字符,并且填写跟需要提交的数据一并提交给服务器。服务器在收到这些数据后,会首先判断图片上的字符串跟之前生成的字符串是否一致,一致则说明提交合法,反之不合法。

     

那么我们今天通过python中的常用的web框架tornado来实现一个图形验证码。通过tornado搭建一个web服务器是非常容易的。下面的代码就是一个通过tornado实现的web服务器。

 Tornado框架实现图形验证码功能

我们将这段代码运行之后,打开浏览器输入http://127.0.0.1:8080/index,如果一切正常你会得到如下页面。

 Tornado框架实现图形验证码功能

我们分别介绍一下这段代码中的每个部分。

 Tornado框架实现图形验证码功能

这段代码是服务器部分,写法固定。其中listem函数中的8080代表的是端口,可以修改成任意端口。

 Tornado框架实现图形验证码功能

这段是路由规则,r”/index”是规则,支持正则表达式。这条路由代表,url“/index”的请求指向IndexHandler。那么我们在浏览器中访问127.0.0.1:8080/index时候,浏览器的请求就会交给IndexHandler来响应。

 Tornado框架实现图形验证码功能

业务处理模块,也是我们开发工作的核心。每一个类对应一个业务功能,所有的类必须继承tornado.web.RequestHandler类,这个类是tornado中用来处理请求的类。上面讲到浏览器访问”/index”,这个请求会被路由转发到IndexHandler类。因为是get请求,所以会执行get方法。Self.write(‘hello world!’),会返回‘hello world!’字符串。所以浏览器也会接收到这个字符串。

谷歌浏览器按f12打开开发者工具,选中network可以查看浏览器发送的http请求,如下图:

 Tornado框架实现图形验证码功能

那么我们要返回一个登录的html页面怎么操作呢?

首先我们需要在服务器端写一个登录的html文件。

Tornado框架实现图形验证码功能

为了简单,直接将这个文件命名为index.html放到当前目录。我们需要修改get方法中的代码。

 Tornado框架实现图形验证码功能

self.render(‘index.html’)会返回‘index.html’页面

重启服务器,再来访问/index,如果一切正常你会得到如下页面

Tornado框架实现图形验证码功能

index.htmlform表单会向action指向的url发送post请求。

 Tornado框架实现图形验证码功能

post请求的url是”/index”,所以我们需要在IndexHandler中再写一个post方法,来处理登录。

Tornado框架实现图形验证码功能

Self.get_argument(‘user’) 可以获取post请求中发过来的数据,参数user对应html中form标签里的元素的name。

Tornado框架实现图形验证码功能

重启服务器,我们再次访问index页面,在用户名密码里输入admin123如果一切正常,将显示如下页面:

Tornado框架实现图形验证码功能

那么我们今天需要添加一个图形验证码的功能。首先需要修改前端页面如下:

Tornado框架实现图形验证码功能

增加一个显示验证码的图片标签,一个输入验证码的input标签,重启服务器再次访问

Tornado框架实现图形验证码功能

方框部分就是验证码,因为我们的图片指向的url/check_code但是我们的服务器中还没有,所以获取不到图片,那么我们就需要来写一个返回验证码图片的业务模块。

 

验证码处理模块,需要生成一个随机字符串,并且还要返回这个随机字符串生成的图片。Python3中处理图形图形的模块是pillow,2中是PIL通过这个模块,我们写一个生成随机字符串,和对应图片的函数。因为我们这个里主要是介绍验证码的原理,所以这个函数我们不细讲,有兴趣的朋友可以加我的qq 2446867994,我将这个函数文件发给大家。验证码处理模块代码如下:

Tornado框架实现图形验证码功能

一定记得还要添加一条路由

(r"/check_code", CheckCodeHandler),

 

重启服务器,再次访问登录页面,如果没有错误会得到如下页面:

Tornado框架实现图形验证码功能

到这里我们的图形验证码就实现成功,我们只需要在登录的时候去验证用户输入的验证码和生成图片的code是否一致就判断是否是人工登录。那么业务业务逻辑的设计我们今天不讨论。我们这个验证码还有一个缺点,因为图片加了噪点,扭曲,有时候可能不好辨认,我们需要换一张验证码。我们下面通过一段js来实现点击验证码图片来刷新的功能。代码如下:

Tornado框架实现图形验证码功能

重启服务器,再次登录页面,那么如果没有错误,点击验证码就可以实现刷新验证码了。