python生成验证码

原创 Laughing  2018-10-04 13:58  阅读 495 次 评论 0 条

依赖PIL

pip install pillow

公共方法

  1. import hashlib  
  2. import random  
  3. import string  
  4.   
  5. from PIL import Image, ImageFont, ImageDraw, ImageFilter  
  6. from flask import Flask  
  7.   
  8. app = Flask(__name__)  
  9.   
  10. app.config.from_object("config.DevelopmentConfig")  # 从config.py读入配置  
  11.   
  12.   
  13. def rndColor():  
  14.     """随机颜色"""  
  15.     return random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)  
  16.   
  17.   
  18. def gene_text():  
  19.     """生成4位验证码"""  
  20.     return ''.join(random.sample(string.ascii_letters + string.digits, 4))  
  21.   
  22.   
  23. def draw_lines(draw, num, width, height):  
  24.     """划线"""  
  25.     for num in range(num):  
  26.         x1 = random.randint(0, width / 2)  
  27.         y1 = random.randint(0, height / 2)  
  28.         x2 = random.randint(0, width)  
  29.         y2 = random.randint(height / 2, height)  
  30.         draw.line(((x1, y1), (x2, y2)), fill='black', width=1)  
  31.   
  32.   
  33. def get_verify_code():  
  34.     """生成验证码图形"""  
  35.     code = gene_text()  
  36.     # 图片大小120×50  
  37.     width, height = 100, 40  
  38.     # 新图片对象  
  39.     im = Image.new('RGB', (width, height), 'white')  
  40.     # 字体  
  41.     font = ImageFont.truetype('app/static/arial.ttf', 30)  
  42.     # draw对象  
  43.     draw = ImageDraw.Draw(im)  
  44.     # 绘制字符串  
  45.     for item in range(4):  
  46.         draw.text((5 + random.randint(-3, 3) + 23 * item, 5 + random.randint(-3, 3)),  
  47.                   text=code[item], fill=rndColor(), font=font)  
  48.     # 划线  
  49.     draw_lines(draw, 2, width, height)  
  50.     # 高斯模糊  
  51.     im = im.filter(ImageFilter.GaussianBlur(radius=1.5))  
  52.     return im, code  
  53.   
  54.   
  55. def salted_password(password):  
  56.     salt = app.config.get('SALT_KEY')  
  57.     hsobj = hashlib.sha256(salt.encode("utf-8"))  
  58.     hsobj.update(password.encode("utf-8"))  
  59.     return hsobj.hexdigest().upper()  

调用

  1. from app import app  
  2. from flask import render_template, request, session, redirect, make_response,url_for,flash  
  3. from app import db  
  4. from app.functions import get_verify_code, salted_password  
  5. import re  
  6. from app.models import Users,UsersJson,Menus,MenuDto  
  7. import datetime  
  8. from io import BytesIO  
  9. from app.PubFunc.EmailHelp import EmailCls  
  10. import json  
  11. from datetime import timedelta  
  12. import threading  
  13.   
  14. @app.route('/code')  
  15. def get_code():  
  16.     image, code = get_verify_code()  
  17.     # 图片以二进制形式写入  
  18.     buf = BytesIO()  
  19.     image.save(buf, 'jpeg')  
  20.     buf_str = buf.getvalue()  
  21.     # 把buf_str作为response返回前端,并设置首部字段  
  22.     response = make_response(buf_str)  
  23.     response.headers['Content-Type'] = 'image/gif'  
  24.     # 将验证码字符串储存在session中  
  25.     session['verifyCode'] = code  
  26.     return response  
  27.   
  28. @app.route('/')  
  29. def main():  
  30.     if 'userName' not in session or session['userName'] == None or session['userName'] == '':  
  31.         return redirect('login')  
  32.     # email = EmailCls()  
  33.     # emailInfo = email.getEmail()  
  34.     # t= threading.Thread(target=email.getEmail)  
  35.     # t.setDaemon(True)  
  36.     # t.start()  
  37.     # t.join()  
  38.     menus = test_set_subMenus()  
  39.     return render_template('index.html',userinfo=json.loads(session['userinfo']),emailInfo=None,menus=menus)  
  40.   
  41. @app.route('/logout')  
  42. def logout():  
  43.     session.clear  
  44.     return redirect('/login')  
  45.   
  46. @app.route('/login', methods=['GET', 'POST'])  
  47. def login():  
  48.     if (request.method == 'GET'):  
  49.         return render_template('login.html')  
  50.     else:  
  51.         username = request.form.get('userlogin')  
  52.         password = request.form.get('loginpassword')  
  53.         verifyCode = request.form.get('loginverifycode')  
  54.         rememberme = request.form.get('rememberme')  
  55.         remembermemonth = request.form.get('remembermemonth')  
  56.         if rememberme=='on':  
  57.             app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)  #配置7天有效  
  58.             session.permanent = timedelta(days=7)  
  59.         if remembermemonth=='on':  
  60.             app.config['PERMANENT_SESSION_LIFETIME'] = True # 长期有效,一个月的时间有效  
  61.             session.permanent = True # 长期有效,一个月的时间有效  
  62.         if 'verifyCode' not in session or session['verifyCode'] == None or session['verifyCode'] == '':  
  63.             return redirect('login')  
  64.         if verifyCode == None or verifyCode == '':  
  65.             return '请输入验证码'  
  66.         if verifyCode.upper() != session['verifyCode'].upper():  
  67.             return '验证码输入不正确'  
  68.         if username == None or username == '':  
  69.             return '请输入用户名'  
  70.         if password == None or password == '':  
  71.             return '请输入密码'  
  72.         user = db.session.query(Users).filter_by(user_login=username).first()  
  73.         if user == None:  
  74.             return '当前用户尚未注册'  
  75.         if not user.user_pass == salted_password(password):  
  76.             return '密码输入不正确'  
  77.         session['userName'] = username  
  78.         session['userinfo']=json.dumps(user,default=UsersJson)  
  79.         return redirect('/')  
  80.   
  81.   
  82. @app.route('/register', methods=['POST', ])  
  83. def register():  
  84.     username = request.form.get('regusername')  
  85.     password = request.form.get('regpassword')  
  86.     verifyCode = request.form.get('regverifycode')  
  87.     userEmail = request.form.get('regemail')  
  88.   
  89.     if username == None or username == '':  
  90.         return '请输入用户名'  
  91.     if userEmail == None or userEmail == '':  
  92.         return '请输入邮箱'  
  93.     if not re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net,me,org,com.cn.cc.co]{1,3}$', userEmail):  
  94.         return '邮箱格式不正确'  
  95.     if password == None or password == '':  
  96.         return '请输入密码'  
  97.     if verifyCode.upper() != session['verifyCode'].upper():  
  98.         return '验证码输入不正确'  
  99.     user = Users()  
  100.     user.user_login = username  
  101.     user.user_email = userEmail  
  102.     user.user_pass = salted_password(password)  
  103.     user.user_nicename = username  
  104.     user.user_registered = datetime.datetime.now()  
  105.     user.user_status = 1  
  106.     user.display_name = username  
  107.     sql = 'SELECT 1 FROM Users where user_login=:username or user_email=:user_email'  
  108.     userExist = db.session.execute(sql, {'username': username, 'user_email': userEmail})  
  109.     if len(userExist.fetchall()) > 0:  
  110.         return '当前用户已存在或者邮箱已被注册'  
  111.     db.session.add(user)  
  112.     db.session.commit()  
  113.     return redirect('/')  
  114.   
  115.   
  116. @app.route('/welcome_iframe.html')  
  117. def elements():  
  118.     return render_template('welcome_iframe.html')  
  119.   
  120. @app.route('/UI/buttons_iframe.html')  
  121. def buttons():  
  122.     return render_template('UI/buttons_iframe.html')  
  123.   
  124. @app.route('/UI/general_iframe.html')  
  125. def general_iframe():  
  126.     return render_template('UI/general_iframe.html')  
  127.   
  128. @app.route('/UI/icons_iframe.html')  
  129. def icons_iframe():  
  130.     return render_template('UI/icons_iframe.html')  
  131.   
  132. @app.route('/UI/modals_iframe.html')  
  133. def modals_iframe():  
  134.     return render_template('UI/modals_iframe.html')  
  135.   
  136. @app.route('/UI/sliders_iframe.html')  
  137. def sliders_iframe():  
  138.     return render_template('UI/sliders_iframe.html')  
  139.   
  140. @app.route('/UI/timeline_iframe.html')  
  141. def timeline_iframe():  
  142.     return render_template('UI/timeline_iframe.html')  
  143.   
  144.   
  145.   
  146. def queryByParent(parentid):  
  147.     menus = db.session.query(Menus).filter_by(parentid=parentid).all()  
  148.     return menus  
  149.   
  150.   
  151. def set_subMenus(id, menus):  
  152.     """ 
  153.     根据传递过来的父菜单id,递归设置各层次父菜单的子菜单列表 
  154.  
  155.     :param id: 父级id 
  156.     :param menus: 子菜单列表 
  157.     :return: 如果这个菜单没有子菜单,返回None;如果有子菜单,返回子菜单列表 
  158.     """  
  159.     # 记录子菜单列表  
  160.     subMenus = []  
  161.     # 遍历子菜单  
  162.     for m in menus:  
  163.         if m.parentid == id:  
  164.             subMenus.append(m)  
  165.   
  166.     # 把子菜单的子菜单再循环一遍  
  167.     for sub in subMenus:  
  168.         menus2 = queryByParent(sub.id)  
  169.         # 还有子菜单  
  170.         if len(menus):  
  171.             sub.subMenus = set_subMenus(sub.id, menus2)  
  172.   
  173.     # 子菜单列表不为空  
  174.     if len(subMenus):  
  175.         return subMenus  
  176.     else:  # 没有子菜单了  
  177.         return None  
  178.   
  179.   
  180. def test_set_subMenus():  
  181.     # 一级菜单  
  182.     rootMenus = queryByParent('0')  
  183.     for menu in rootMenus:  
  184.         subMenus = queryByParent(menu.id)  
  185.         menu.subMenus = set_subMenus(menu.id, subMenus)  
  186.     jsonData = json.dumps(rootMenus,default=MenuDto,ensure_ascii=False)  
  187.     return jsonData  

前台

  1. <!DOCTYPE html>  
  2. <html lang="en">  
  3.     <head>  
  4.         <meta charset="utf-8" />  
  5.         <title>开发框架</title>  
  6.         <meta name="keywords" content="开发框架" />  
  7.         <meta name="description" content="开发框架" />  
  8.         <meta name="viewport" content="width=device-width, initial-scale=1.0" />  
  9.         <!-- basic styles -->  
  10.         <link href="/static/css/bootstrap.min.css" rel="stylesheet" />  
  11.         <link rel="stylesheet" href="/static/css/font-awesome.min.css" />  
  12.         <link rel="shortcut icon" href="/static/img/favicon.ico"/>  
  13.   
  14.         <link rel="stylesheet" href="/static/css/font.googleapis.com.css" />  
  15.   
  16.         <link rel="stylesheet" href="/static/css/ace.min.css" />  
  17.         <link rel="stylesheet" href="/static/css/ace-rtl.min.css" />  
  18.   
  19.     </head>  
  20.   
  21.     <body class="login-layout">  
  22.         <div class="main-container">  
  23.             <div class="main-content">  
  24.                 <div class="row">  
  25.                     <div class="col-sm-10 col-sm-offset-1">  
  26.                         <div class="login-container">  
  27.                             <div class="center">  
  28.                                 <h1>  
  29.                                     <i class="fa fa-leaf green"></i>  
  30.                                     <a href="https://www.erpdev.cn"><span class="red">ErpDev.Cn</span></a>  
  31.                                     <br/>  
  32.                                     <span class="white">基于Python的开发框架</span>  
  33.                                 </h1>  
  34.                                 <h4 class="blue">&copycopy; <a href="https://www.lisen.org">李森的博客</a></h4>  
  35.                             </div>  
  36.   
  37.                             <div class="space-6"></div>  
  38.   
  39.                             <div class="position-relative">  
  40.                                 <div id="login-box" class="login-box visible widget-box no-border">  
  41.                                     <div class="widget-body">  
  42.                                         <div class="widget-main">  
  43.                                             <h4 class="header blue lighter bigger">  
  44.                                                 <i class="icon-coffee green"></i>  
  45.                                                 请输入个人信息  
  46.                                             </h4>  
  47.   
  48.                                             <div class="space-6"></div>  
  49.   
  50.                                               <form action="{{ url_for("login") }}" method="post" name="loginform" id="loginform">  
  51.                                                 <fieldset>  
  52.                                                     <label class="block clearfix">  
  53.                                                         <span class="block input-icon input-icon-right">  
  54.                                                             <input type="text" id="userlogin" name="userlogin" class="form-control" placeholder="请输入用户名" required minlength="4" maxlength="30" />  
  55.                                                             <i class="icon-user"></i>  
  56.                                                         </span>  
  57.                                                     </label>  
  58.   
  59.                                                     <label class="block clearfix">  
  60.                                                         <span class="block input-icon input-icon-right">  
  61.                                                             <input type="password" id="loginpassword" name="loginpassword" class="form-control" placeholder="请输入密码" required minlength="8" />  
  62.                                                             <i class="icon-lock"></i>  
  63.                                                         </span>  
  64.                                                     </label>  
  65.                                                       
  66.                                                     <label class="block clearfix">  
  67.                                                         <span class="block input-icon input-icon-right">  
  68.                                                             <div class="row">  
  69.                                                                 <div class="col-sm-4 col-xs-4">  
  70.                                                             <img id="loginverifycodeImg" src="/code" />  
  71.                                                         </div>  
  72.                                                         <div class="col-sm-8 col-xs-8">  
  73.                                                             <input type="text" id="loginverifycode" name="loginverifycode" class="form-control" placeholder="请输入验证码" required minlength="4" maxlength="4" />  
  74.                                                             </div>  
  75.                                                             </div>  
  76.                                                             <i class="icon-lock"></i>  
  77.                                                         </span>  
  78.                                                     </label>  
  79.   
  80.                                                     <div class="space"></div>  
  81.   
  82.                                                     <div class="clearfix">  
  83.                                                         <label class="inline">  
  84.                                                             <input type="checkbox" class="ace" id="rememberme" name="rememberme"/>  
  85.                                                             <span class="lbl">记住我(7天)</span>  
  86.                                                         </label>  
  87.                                                         <label class="inline">  
  88.                                                             <input type="checkbox" class="ace" id="remembermemonth" name="remembermemonth"/>  
  89.                                                             <span class="lbl">记住我(1个月)</span>  
  90.                                                         </label>  
  91.                                                         <button type="submit" class="width-35 pull-right btn btn-sm btn-primary">  
  92.                                                             <i class="icon-key"></i>  
  93.                                                             登录  
  94.                                                         </button>  
  95.                                                     </div>  
  96.   
  97.                                                     <div class="space-4"></div>  
  98.                                                 </fieldset>  
  99.                                             </form>  
  100.   
  101.                                             <div class="social-or-login center">  
  102.                                                 <span class="bigger-110">通过以下方式登录</span>  
  103.                                             </div>  
  104.   
  105.                                             <div class="social-login center">  
  106.                                                 <a class="btn btn-primary">  
  107.                                                     <i class="fa fa-qq"></i>  
  108.                                                 </a>  
  109.   
  110.                                                 <a class="btn btn-info">  
  111.                                                     <i class="fa fa-wechat"></i>  
  112.                                                 </a>  
  113.   
  114.                                                 <a class="btn btn-danger">  
  115.                                                     <i class="fa fa-weibo"></i>  
  116.                                                 </a>  
  117.                                             </div>  
  118.                                         </div><!-- /widget-main -->  
  119.   
  120.                                         <div class="toolbar clearfix">  
  121.                                             <div>  
  122.                                                 <a href="#" onclick="show_box('forgot-box'); return false;" class="forgot-password-link">  
  123.                                                     <i class="icon-arrow-left"></i>  
  124.                                                     忘记密码?  
  125.                                                 </a>  
  126.                                             </div>  
  127.   
  128.                                             <div>  
  129.                                                 <a href="#" onclick="show_box('signup-box'); return false;" class="user-signup-link">  
  130.                                                     注册  
  131.                                                     <i class="icon-arrow-right"></i>  
  132.                                                 </a>  
  133.                                             </div>  
  134.                                         </div>  
  135.                                     </div><!-- /widget-body -->  
  136.                                 </div><!-- /login-box -->  
  137.   
  138.                                 <div id="forgot-box" class="forgot-box widget-box no-border">  
  139.                                     <div class="widget-body">  
  140.                                         <div class="widget-main">  
  141.                                             <h4 class="header red lighter bigger">  
  142.                                                 <i class="icon-key"></i>  
  143.                                                 找回密码  
  144.                                             </h4>  
  145.   
  146.                                             <div class="space-6"></div>  
  147.                                             <p>  
  148.                                                 请输入邮箱  
  149.                                             </p>  
  150.   
  151.                                             <form>  
  152.                                                 <fieldset>  
  153.                                                     <label class="block clearfix">  
  154.                                                         <span class="block input-icon input-icon-right">  
  155.                                                             <input type="emailclass="form-control" placeholder="邮箱" />  
  156.                                                             <i class="icon-envelope"></i>  
  157.                                                         </span>  
  158.                                                     </label>  
  159.   
  160.                                                     <div class="clearfix">  
  161.                                                         <button type="button" class="width-35 pull-right btn btn-sm btn-danger">  
  162.                                                             <i class="icon-lightbulb"></i>  
  163.                                                             发送  
  164.                                                         </button>  
  165.                                                     </div>  
  166.                                                 </fieldset>  
  167.                                             </form>  
  168.                                         </div><!-- /widget-main -->  
  169.   
  170.                                         <div class="toolbar center">  
  171.                                             <a href="#" onclick="show_box('login-box'); return false;" class="back-to-login-link">  
  172.                                                 登录  
  173.                                                 <i class="icon-arrow-right"></i>  
  174.                                             </a>  
  175.                                         </div>  
  176.                                     </div><!-- /widget-body -->  
  177.                                 </div><!-- /forgot-box -->  
  178.   
  179.                                 <div id="signup-box" class="signup-box widget-box no-border">  
  180.                                     <div class="widget-body">  
  181.                                         <div class="widget-main">  
  182.                                             <h4 class="header green lighter bigger">  
  183.                                                 <i class="icon-group blue"></i>  
  184.                                                 注册  
  185.                                             </h4>  
  186.   
  187.                                             <div class="space-6"></div>  
  188.                                             <p> 请输入个人信息: </p>  
  189.   
  190.                                             <form action="register" method="POST">  
  191.                                                 <fieldset>  
  192.                                                     <label class="block clearfix">  
  193.                                                         <span class="block input-icon input-icon-right">  
  194.                                                             <input type="emailid="regemail" name="regemail" class="form-control" placeholder="请输入邮箱" required maxlength="100" />  
  195.                                                             <i class="icon-envelope"></i>  
  196.                                                         </span>  
  197.                                                     </label>  
  198.   
  199.                                                     <label class="block clearfix">  
  200.                                                         <span class="block input-icon input-icon-right">  
  201.                                                             <input type="text" id="regusername" name="regusername" class="form-control" placeholder="请输入用户名" required maxlength="30" minlength="4" />  
  202.                                                             <i class="icon-user"></i>  
  203.                                                         </span>  
  204.                                                     </label>  
  205.   
  206.                                                     <label class="block clearfix">  
  207.                                                         <span class="block input-icon input-icon-right">  
  208.                                                             <input type="password" id="regpassword" name="regpassword" class="form-control" placeholder="请输入密码" required minlength="8" maxlength="100" />  
  209.                                                             <i class="icon-lock"></i>  
  210.                                                         </span>  
  211.                                                     </label>  
  212.   
  213.                                                     <label class="block clearfix">  
  214.                                                         <span class="block input-icon input-icon-right">  
  215.                                                             <input type="password" id="regcomfirmpassword" name="regcomfirmpassword" class="form-control" placeholder="请再次输入密码" required equalTo:"#regpassword" />  
  216.                                                             <i class="icon-retweet"></i>  
  217.                                                         </span>  
  218.                                                     </label>  
  219.                                                       
  220.                                                     <label class="block clearfix">  
  221.                                                         <span class="block input-icon input-icon-right">  
  222.                                                             <div class="row">  
  223.                                                                 <div class="col-sm-4 col-xs-4">  
  224.                                                             <img src="/code" />  
  225.                                                         </div>  
  226.                                                         <div class="col-sm-8 col-xs-8">  
  227.                                                             <input type="text" id="regverifycode" name="regverifycode" class="form-control" placeholder="验证码" required="true" maxlength="4" minlength="4" />  
  228.                                                             </div>  
  229.                                                             </div>  
  230.                                                             <i class="icon-lock"></i>  
  231.                                                         </span>  
  232.                                                     </label>  
  233.   
  234.                                                     <label class="block">  
  235.                                                         <input type="checkbox" class="ace" required />  
  236.                                                         <span class="lbl">  
  237.                                                             我同意  
  238.                                                             <a href="#">用户协议</a>  
  239.                                                         </span>  
  240.                                                     </label>  
  241.   
  242.                                                     <div class="space-24"></div>  
  243.   
  244.                                                     <div class="clearfix">  
  245.                                                         <button type="reset" class="width-30 pull-left btn btn-sm">  
  246.                                                             <i class="icon-refresh"></i>  
  247.                                                             取消  
  248.                                                         </button>  
  249.   
  250.                                                         <button type="submit" class="width-65 pull-right btn btn-sm btn-success">  
  251.                                                             注册  
  252.                                                             <i class="icon-arrow-right icon-on-right"></i>  
  253.                                                         </button>  
  254.                                                     </div>  
  255.                                                 </fieldset>  
  256.                                             </form>  
  257.                                         </div>  
  258.   
  259.                                         <div class="toolbar center">  
  260.                                             <a href="#" onclick="show_box('login-box'); return false;" class="back-to-login-link">  
  261.                                                 <i class="icon-arrow-left"></i>  
  262.                                                 登录  
  263.                                             </a>  
  264.                                         </div>  
  265.                                     </div><!-- /widget-body -->  
  266.                                 </div><!-- /signup-box -->  
  267.                             </div><!-- /position-relative -->  
  268.                         </div>  
  269.                     </div><!-- /.col -->  
  270.                 </div><!-- /.row -->  
  271.             </div>  
  272.         </div><!-- /.main-container -->  
  273.   
  274.         <!-- basic scripts -->  
  275.   
  276.         <!--[if !IE]> -->  
  277.   
  278.         <script type="text/javascript">  
  279.             window.jQuery || document.write("<script src='/static/js/jQuery/jquery-2.2.3.min.js'>"+"<"+"/script>");  
  280.         </script>  
  281.         <script type="text/javascript" src="/static/js/jQuery/jquery.validate.min.js"></script>  
  282.         <!-- <![endif]-->  
  283.   
  284.         <!--[if IE]>  
  285. <script type="text/javascript">  
  286.  window.jQuery || document.write("<script src='/static/js/jquery-1.10.2.min.js'>"+"<"+"/script>");  
  287. </script>  
  288. <![endif]-->  
  289.   
  290.         <script type="text/javascript">  
  291.             if("ontouchend" in document) document.write("<script src='/static/js/jQuery/jquery.mobile.custom.min.js'>"+"<"+"/script>");  
  292.         </script>  
  293.   
  294.         <!-- inline scripts related to this page -->  
  295.   
  296.         <script type="text/javascript">  
  297.   
  298.             $(function(){  
  299.                 $("#loginverifycodeImg").click(function(){  
  300.                     $('#loginverifycodeImg').attr('src',"/code?t="+Date());  
  301.                 })  
  302.             })  
  303.   
  304.             function show_box(id) {  
  305.              jQuery('.widget-box.visible').removeClass('visible');  
  306.              jQuery('#'+id).addClass('visible');  
  307.             }  
  308.         </script>  
  309.       
  310. </body>  
  311. </html>  

本文地址:https://www.lisen.me/python-generates-verification-code.html
版权声明:本文为原创文章,版权归 木子网 所有,欢迎分享本文,转载请保留出处!

发表评论


表情