tornado 驗證碼生成+結合session進行登入驗證
阿新 • • 發佈:2019-02-03
第一、生成驗證碼圖片
生成驗證碼圖片需要兩個必須模組
1、python自帶的random(隨機模組)
2、Pillow()影象處理模組裡的PIL(影象庫),為第三方模組,需要安裝
封裝驗證碼圖片生成外掛py
在封裝檔案裡先匯入random(隨機模組),和Pillow()影象處理模組裡的所需py檔案
封裝驗證碼圖片生成外掛功能,呼叫後返回驗證碼圖片,和字串型別驗證碼,兩個返回值
注意:驗證碼需要一個字型檔案,這個字型檔案必須和封裝建立放在一起
驗證碼圖片生成外掛py
#!/usr/bin/env python #coding:utf-8 import random from PIL import Image, ImageDraw, ImageFont, ImageFilter _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小寫字母,去除可能干擾的i,l,o,z _upper_cases = _letter_cases.upper() # 大寫字母 _numbers = ''.join(map(str, range(3, 10))) # 數字 init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) def create_validate_code(size=(120, 30), chars=init_chars, img_type="GIF", mode="RGB", bg_color=(255, 255, 255), fg_color=(0, 0, 255), font_size=18, font_type="Monaco.ttf", length=4, draw_lines=True, n_line=(1, 2), draw_points=True, point_chance = 2): ''' @todo: 生成驗證碼圖片 @param size: 圖片的大小,格式(寬,高),預設為(120, 30) @param chars: 允許的字元集合,格式字串 @param img_type: 圖片儲存的格式,預設為GIF,可選的為GIF,JPEG,TIFF,PNG @param mode: 圖片模式,預設為RGB @param bg_color: 背景顏色,預設為白色 @param fg_color: 前景色,驗證碼字元顏色,預設為藍色#0000FF @param font_size: 驗證碼字型大小 @param font_type: 驗證碼字型,預設為 ae_AlArabiya.ttf @param length: 驗證碼字元個數 @param draw_lines: 是否劃干擾線 @param n_lines: 干擾線的條數範圍,格式元組,預設為(1, 2),只有draw_lines為True時有效 @param draw_points: 是否畫干擾點 @param point_chance: 干擾點出現的概率,大小範圍[0, 100] @return: [0]: PIL Image例項 @return: [1]: 驗證碼圖片中的字串 ''' width, height = size # 寬, 高 img = Image.new(mode, size, bg_color) # 建立圖形 draw = ImageDraw.Draw(img) # 建立畫筆 def get_chars(): '''生成給定長度的字串,返回列表格式''' return random.sample(chars, length) def create_lines(): '''繪製干擾線''' line_num = random.randint(*n_line) # 干擾線條數 for i in range(line_num): # 起始點 begin = (random.randint(0, size[0]), random.randint(0, size[1])) #結束點 end = (random.randint(0, size[0]), random.randint(0, size[1])) draw.line([begin, end], fill=(0, 0, 0)) def create_points(): '''繪製干擾點''' chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100] for w in range(width): for h in range(height): tmp = random.randint(0, 100) if tmp > 100 - chance: draw.point((w, h), fill=(0, 0, 0)) def create_strs(): '''繪製驗證碼字元''' c_chars = get_chars() strs = ' %s ' % ' '.join(c_chars) # 每個字元前後以空格隔開 font = ImageFont.truetype(font_type, font_size) font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3), strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines: create_lines() if draw_points: create_points() strs = create_strs() # 圖形扭曲引數 params = [1 - float(random.randint(1, 2)) / 100, 0, 0, 0, - float(random.randint(1, 10)) / 100, float(random.randint(1, 2)) / 500, 0.001, float(random.randint(1, 2)) / 500 ] img = img.transform(size, Image.PERSPECTIVE, params) # 建立扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 濾鏡,邊界加強(閾值更大) return img, strs #返回驗證碼圖片,和字串型別驗證碼
驗證碼圖片生成外掛py使用方法
在驗證碼HTML的,img標籤的src圖片地址,路由對映的邏輯處理函式裡使用
首先在要顯示驗證碼圖片的html,img標籤的src="/yanzhma",一個路由對映路徑
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>請登入</h1> <form method="post" action="/dlu"> 使用者名稱<input type="text" name="yhm"/><br/><br/> 密碼<input type="text" name="mim"/><br/><br/> 驗證碼<input type="text" name="yanzhma"/><br/><br/> <img src="/yanzhma"><br/><br/> <input type="submit" value="提交"/> </form> </body> </html>
在框架引擎,配置這個驗證碼圖片src路由對映路徑,和邏輯處理函式
src路由對映路徑的邏輯處理函式裡使用驗證碼圖片生成外掛
需要匯入io模組,和,生成驗證碼圖片外掛py
框架引擎
#!/usr/bin/env python #coding:utf-8 import tornado.ioloop import tornado.web #匯入tornado模組下的web檔案 import session_lei #匯入session模組 class dluHandler(tornado.web.RequestHandler): def get(self): self.render("dlu.html") #開啟登入頁面 def post(self): yhm = self.get_argument('yhm') #接收使用者提交的使用者名稱 mim = self.get_argument('mim') #接收使用者提交的密碼 class yanzhmaHandler(tornado.web.RequestHandler): def get(self): #生成圖片並且返回 import io #匯入io模組 import check_code #匯入驗證碼圖片生成外掛 mstream = io.BytesIO() #建立一個BytesIO臨時儲存生成圖片資料 img,code = check_code.create_validate_code() #執行圖片生成插進裡的check_code.create_validate_code類,返回驗證碼圖片生成資料,和字串驗證碼 img.save(mstream,"PNG") #將返回的驗證碼圖片資料,新增到BytesIO臨時儲存 self.write(mstream.getvalue()) #從BytesIO臨時儲存,獲取圖片返回給img的 src= 進行顯示 settings = { #html檔案歸類配置,設定一個字典 "template_path":"views", #鍵為template_path固定的,值為要存放HTML的資料夾名稱 "static_path":"statics", #鍵為static_path固定的,值為要存放js和css的資料夾名稱 } #路由對映 application = tornado.web.Application([ #建立一個變數等於tornado.web下的Application方法 (r"/dlu", dluHandler), (r"/yanzhma", yanzhmaHandler), ],**settings) #將html檔案歸類配置字典,寫在路由對映的第二個引數裡 if __name__ == "__main__": #內部socket執行起來 application.listen(8888) #設定埠 tornado.ioloop.IOLoop.instance().start()
利用js實現,點選圖片重新整理驗證碼,也就是點選一下發送一次驗證碼請求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>請登入</h1>
<form method="post" action="/dlu">
使用者名稱<input type="text" name="yhm"/><br/><br/>
密碼<input type="text" name="mim"/><br/><br/>
驗證碼<input type="text" name="yanzhma"/><br/><br/>
<img src="/yanzhma" onclick='ChangeCode();' id='imgCode'><br/><br/>
<input type="submit" value="提交"/>
</form>
<script type="text/javascript">
function ChangeCode() {
var code = document.getElementById('imgCode');
code.src += '?';
}
</script>
</body>
</html>
第二、驗證碼結合Session驗證
也就是在匯入Session模組,將字串驗證碼寫入使用者的Session裡,然後判斷使用者輸入的驗證碼和Session裡的驗證碼是否一致
#!/usr/bin/env python
#coding:utf-8
import tornado.ioloop
import tornado.web #匯入tornado模組下的web檔案
import session_lei #匯入session模組
class indexHandler(tornado.web.RequestHandler):
def get(self):
session = session_lei.Session(self, 1) #建立session物件,cookie保留1天
zhuangti = session['zhuangtai'] #獲取使用者cookie對應字典裡的zhuangtai
if zhuangti == True: #判斷zhuangtai是否等於True
self.render("index.html") #說明登陸了顯示檢視頁
else:
self.redirect('/dlu') #跳轉登入頁
class dluHandler(tornado.web.RequestHandler):
def get(self):
session = session_lei.Session(self, 1) #建立session物件,cookie保留1天
zhuangti = session['zhuangtai'] #獲取使用者cookie對應字典裡的zhuangtai
if zhuangti == True: #判斷zhuangtai是否等於True
self.redirect("/index") #說明登陸了跳轉檢視頁
else:
self.render("dlu.html",tishi = '') #開啟登入頁面
def post(self):
yhm = self.get_argument('yhm') #接收使用者提交的使用者名稱
mim = self.get_argument('mim') #接收使用者提交的密碼
if yhm == "admin" and mim == "admin": #判斷使用者名稱和密碼
session = session_lei.Session(self, 1) # 建立session物件,cookie保留1天
session['yhm'] = yhm # 將使用者名稱儲存到session
session['mim'] = mim # 將密碼儲存到session
session['zhuangtai'] = True # 在session寫入登入狀態
shur_yzhm = self.get_argument('yanzhma').upper() #獲取使用者輸入驗證碼,轉換成大寫
session_yzhm = session['yanzhma'].upper() #獲取session裡的驗證碼,轉換成大寫
if shur_yzhm == session_yzhm: #判斷使用者輸入的驗證碼,和session裡的驗證碼是否一致
self.redirect("/index") #跳轉檢視頁
else:
self.render("dlu.html", tishi="驗證碼不正確")
else:
self.render("dlu.html",tishi = "使用者名稱或密碼不正確")
class yanzhmaHandler(tornado.web.RequestHandler):
def get(self):
#生成圖片並且返回
import io #匯入io模組
import check_code #匯入驗證碼圖片生成外掛
mstream = io.BytesIO() #建立一個BytesIO臨時儲存生成圖片資料
img,code = check_code.create_validate_code() #執行圖片生成插進裡的check_code.create_validate_code類,返回驗證碼圖片生成資料,和字串驗證碼
img.save(mstream,"PNG") #將返回的驗證碼圖片資料,新增到BytesIO臨時儲存
self.write(mstream.getvalue()) #從BytesIO臨時儲存,獲取圖片返回給img的 src= 進行顯示
session = session_lei.Session(self, 1) # 建立session物件,cookie保留1天
session['yanzhma'] = code #將字串驗證碼新增到session裡
settings = { #html檔案歸類配置,設定一個字典
"template_path":"views", #鍵為template_path固定的,值為要存放HTML的資料夾名稱
"static_path":"statics", #鍵為static_path固定的,值為要存放js和css的資料夾名稱
}
#路由對映
application = tornado.web.Application([ #建立一個變數等於tornado.web下的Application方法
(r"/dlu", dluHandler),
(r"/yanzhma", yanzhmaHandler),
(r"/index", indexHandler),
],**settings) #將html檔案歸類配置字典,寫在路由對映的第二個引數裡
if __name__ == "__main__":
#內部socket執行起來
application.listen(8888) #設定埠
tornado.ioloop.IOLoop.instance().start()
原文轉自:http://www.cnblogs.com/adc8868/p/6902829.html