tornado随机生成图片验证码
用python生成随机验证码需要借鉴一个插件,和一个io模块,实现起来也非常容易,当然也需要借鉴session来判断验证码是否错误,下面写一段用户登录验证带验证码的。
一、目录结构
二、login.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>欢迎登录</h1> 9 <form method="POST", action="/login" enctype="multipart/form-data"> 10 <p><input name="username" type="text" placeholder="用户名"></p> 11 <p><input name="pwd" type="password" placeholder="密码"></p> 12 <p> 13 <input name="code" type="text" placeholder="验证码"> 14 <img src="/check_code" onclick="ChangeCode();" id="imgCode"> 15 </p> 16 <input type="submit" value="登录"/> 17 <span style="color: red">{{state}}</span> 18 </form> 19 20 <script type="text/javascript"> 21 function ChangeCode() { //当点击图片的时候,会刷新图片,这一段代码就可以实现 22 var code = document.getElementById('imgCode'); 23 code.src += '?'; 24 } 25 26 </script> 27 28 </body> 29 </html>
三、app.py
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 import tornado.ioloop 4 import tornado.web 5 import io 6 import check_code 7 8 container = {} 9 class Session: 10 def __init__(self, handler): 11 self.handler = handler 12 self.random_str = None 13 14 def __genarate_random_str(self): 15 import hashlib 16 import time 17 obj = hashlib.md5() 18 obj.update(bytes(str(time.time()), encoding='utf-8')) 19 random_str = obj.hexdigest() 20 return random_str 21 22 def __setitem__(self, key, value): 23 #在container中加入随机字符串 24 #定义专属于自己的数据 25 #在客户端中写入随机字符串 26 #判断,请求的用户是否已有随机字符串 27 if not self.random_str: 28 random_str = self.handler.get_cookie('__session__') 29 if not random_str: 30 random_str = self.__genarate_random_str() 31 container[random_str] = {} 32 else: 33 #客户端有随机字符串 34 if random_str in container.keys(): 35 pass 36 else: 37 random_str = self.__genarate_random_str() 38 container[random_str] = {} 39 self.random_str = random_str 40 41 container[self.random_str][key] = value 42 self.handler.set_cookie("__session__", self.random_str) 43 44 def __getitem__(self, key): 45 #获取客户端的随机字符串 46 #从container中获取专属于自己的数据 47 #专属信息[key] 48 random_str = self.handler.get_cookie("__session__") 49 if not random_str: 50 return None 51 #客户端有随机字符串 52 user_info_dict = container.get(random_str, None) 53 if not user_info_dict: 54 return None 55 value = user_info_dict.get(key, None) 56 return value 57 58 class BaseHandler(tornado.web.RequestHandler): 59 def initialize(self): 60 self.session = Session(self) 61 62 63 class LoginHandler(BaseHandler): 64 def get(self, *args, **kwargs): 65 self.render('login.html', state='') 66 67 def post(self, *args, **kwargs): 68 username = self.get_argument('username', None) 69 pwd = self.get_argument('pwd', None) 70 code = self.get_argument('code') 71 check_code = self.session['CheckCode'] 72 if username == 'admin' and pwd == '123' and code.upper() == check_code.upper(): 73 self.write('登录成功') 74 else: 75 self.render('login.html', state='用户信息或验证码不正确') 76 77 class CheckCodeHandler(BaseHandler): 78 def get(self, *args, **kwargs): 79 mstream = io.BytesIO() 80 img, code = check_code.create_validate_code() 81 img.save(mstream, "GIF") 82 self.session['CheckCode'] = code 83 print(mstream.getvalue()) 84 self.write(mstream.getvalue()) 85 86 87 settings = { 88 'template_path': 'views', 89 'static_path': 'static', 90 'cookie_secret': 'hafhdahqahefihdkasfka', 91 } 92 93 application = tornado.web.Application([ 94 (r"/login", LoginHandler), 95 (r"/check_code", CheckCodeHandler), 96 ], **settings) 97 98 if __name__ == "__main__": 99 application.listen(8080) 100 tornado.ioloop.IOLoop.instance().start()
四、check_code.py 和 Monaco.ttf 是一个插件,需要跟app.py放在同一个目录下。
五、运行结果图示