flask中使用验证码

图片检验码, web框架用的是layui

安装

  pip install pillow

views.py

生成验证码

from flask import render_template, request, redirect, url_for, session, make_response
from PIL import Image, ImageFont, ImageDraw, ImageFilter
from io import BytesIO

def validate_picture(width=130, heigth=50):
    # 生成一个临时随机的字符串
    nonce = ‘‘.join([random.choice([chr(random.randrange(97, 122)), str(random.randint(0, 9)),
                                    chr(random.randrange(65, 90))]) for i in range(5)])
    # 生成一个图片对象    颜色, (宽,高), 颜色 三色随机
    imgobj = Image.new(‘RGB‘, (width, heigth), color=tuple([random.randint(0, 255) for i in range(3)]))
    draw = ImageDraw.Draw(imgobj)   # 创建draw对象

    font = ImageFont.truetype(‘/static/font/msyh.ttf‘, size=30)  # 设置字体, 字体大小
    draw.text((10, 4), text=nonce, fill=‘black‘, font=font)  # 用画笔在板子上画出来,

    # 划几根干扰线
    for num in range(8):
        x1 = random.randint(0, width / 2)
        y1 = random.randint(0, heigth / 2)
        x2 = random.randint(0, width)
        y2 = random.randint(heigth / 2, heigth)
        draw.line(((x1, y1), (x2, y2)), fill=‘black‘, width=1)

    # 模糊下,加个帅帅的滤镜~
    im = imgobj.filter(ImageFilter.FIND_EDGES)
    return im, nonce

@auther.route(‘/validate_code‘)
def validate_code():
    image, nonce = validate_picture()
    buf = BytesIO()
    image.save(buf, ‘jpeg‘)
    # 读取写入后的二进制文件
    data = buf.getvalue()
    # 把二进制作为response发回前端,并设置首部字段
    response = make_response(data)
    response.headers[‘Content-Type‘] = ‘image/jpeg‘
    # 添加session, 在session中在次进行判断
    session[‘image‘] = nonce
    return response

登陆类

# 主页
@auther.route(‘/‘)
def loginindex():
    return render_template(‘authentication/login.html‘)

class Login(Resource):
    def post(self):
        ‘‘‘
            状态码  10000: 表示已激活 可以登陆
                    10001:  帐号或密码错误
                    10002: 没有激活
                    10003: 验证码不对
        # 1、检查用户是否存在
        # 2、检查用户是否激活,没有就直接 return
        # 3、如果正常返回url
        ‘‘‘
        print(session)
        res = {‘code‘: 10001}  # 直接判断不存在
        logdic = request.form.to_dict()  # 获取字典
        username = User.query.filter_by(name=logdic["name"]).first()
        if username:
            if username.is_active:
                if session.get(‘image‘):
                                # 不区分大小写
                    if session.get(‘image‘).lower() != logdic["vercode"].lower():
                        res["code"] = 10003
                if username.verify_password(logdic["password"]):
                    login_user(username)
                    session[‘name‘] = logdic[‘name‘]
                    res["url"] = request.args.get(‘next‘) or url_for("backend.index")
                    res["code"] = 10000
            else:
                res["code"] = 10002
        return res

__init__.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 蓝图
from flask import Blueprint
# restful
from flask_restful import Api
auther = Blueprint(‘auther‘,__name__)
# 注册restful
restfulApi = Api(auther)
# 注意蓝图在__init__.py文件中 必须导入views视图
from . import views

model.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#

from app import db, login_manager
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin

class User(UserMixin, db.Model):
    __tablename__ = ‘users‘
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True)
    email = db.Column(db.String(40), unique=True, nullable=True)
    password_hash = db.Column(db.String(128))
    is_active = db.Column(db.Boolean, default=False)

    @property
    def password(self):
        raise AttributeError("输入错误")

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

# 加载用户回调函数
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

html

login.html

{% extends ‘authentication/base.html‘ %}
{% block title %} 登入 - 黑熊平台 {% endblock %}

{% block content %}
    <div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login" style="display: none;">

        <div class="layadmin-user-login-main">
            <div class="layadmin-user-login-box layadmin-user-login-header">
                <h2>黑熊平台</h2>
                <p>后台管理系统</p>
            </div>
            <div class="layadmin-user-login-box layadmin-user-login-body layui-form">
                <div class="layui-form-item">
                    <label class="layadmin-user-login-icon layui-icon layui-icon-username"
                           for="LAY-user-login-username"></label>
                    <input type="text" name="name" id="LAY-user-login-username" lay-verify="required" placeholder="用户名"
                           class="layui-input">
                </div>
                <div class="layui-form-item">
                    <label class="layadmin-user-login-icon layui-icon layui-icon-password"
                           for="LAY-user-login-password"></label>
                    <input type="password" name="password" id="LAY-user-login-password" lay-verify="required"
                           placeholder="密码" class="layui-input">
                </div>

                <div class="layui-form-item">
                    <div class="layui-row">
                        <div class="layui-col-xs7">
                            <label class="layadmin-user-login-icon layui-icon layui-icon-vercode"
                                   for="LAY-user-login-vercode"></label>
                            <input type="text" name="vercode" id="LAY-user-login-vercode" lay-verify="required"
                                   placeholder="图形验证码" class="layui-input">
                        </div>
                        <div class="layui-col-xs5">
                            <div style="margin-left: 10px;">
                                <img src="{{ url_for(‘auther.validate_code‘) }}" id="validate">
                            </div>
                        </div>
                    </div>
                </div>

            <div class="layui-form-item">
                <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="LAY-user-login-submit">登 入</button>
            </div>

            <div class="layui-trans layui-form-item layadmin-user-login-other">
                <label>预留</label>
                <a href="javascript:;"><i class="layui-icon layui-icon-login-qq"></i></a>
                <a href="javascript:;"><i class="layui-icon layui-icon-login-wechat"></i></a>
                <a href="javascript:;"><i class="layui-icon layui-icon-login-weibo"></i></a>

                <a href="{{ url_for(‘auther.register‘) }}" class="layadmin-user-jump-change layadmin-link">注册帐号</a>
            </div>

        </div>
    </div>
    </div>
{% endblock %}

{% block script %}

    {{ super() }}
    <script>
        // 加载模块 form
        layui.use(‘form‘, function () {
            var form = layui.form;
            form.render();    // 更新全部
            form.on(‘submit(LAY-user-login-submit)‘, function (obj) {
                var field = obj.field;
                $.ajax({
                    url: ‘{{ url_for("auther.login") }}‘,
                    type: "post",
                    data: field,
                    success: function (data) {
                        if (data.code == 10000) {
                            window.open(data.url, ‘__self‘);
                        } else if (data.code == 10001) {
                            layer.msg(‘帐号或密码错误,请重新输入‘, {icon: 5})
                        } else if (data.code == 10002) {
                            layer.msg(‘帐户未被激活, 请联系管理员激活‘, {icon: 5})
                        } else if (data.code == 10003){
                            layer.msg(‘验证码不正确,请重新输入‘, {icon: 5})
                        }
                    }
                })
            })
        })
    $("#validate").on(‘click‘, function () {
        $.ajax({
            url: ‘{{ url_for("auther.validate_code") }}‘,
            type:"get",
            success: function (data) {
                $("#validate").attr(‘src‘,"{{ url_for(‘auther.validate_code‘) }}")
            }
        })
    })

    </script>
{% endblock %}

base.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{% block title %} {% endblock %}</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <link rel="stylesheet" href="/static/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="/static/layui/css/admin.css" media="all">
    <link rel="stylesheet" href="/static/layui/css/login.css" media="all">
</head>
<body>
{% block content %}
{% endblock %}

{% block script %}
    <script src="/static/js/jQuery-3.4.1.js"></script>
    <script src="/static/layui/layui.js"></script>
{% endblock %}
</body>
</html>

点击登入,查看后台session

  每次点击之后 点登入 session  image值就会更改
    <RedisSession {‘_permanent‘: True, ‘image‘: ‘29r0i‘,
    <RedisSession {‘_permanent‘: True, ‘image‘: ‘n8091‘,

检验

原文地址:https://blog.51cto.com/xiong51/2429878

时间: 2024-08-30 17:34:49

flask中使用验证码的相关文章

Flask中使用mysql

Flask中使用mysql 先安装相关模块: pip  install  Flask-MySQL 先准备一下数据库 登录: mysql  -u  root  -p 创建Database和创建Table mysql> CREATE DATABASE EmpData; mysql> use EmpData; mysql> CREATE TABLE User( userId INT NOT NULL AUTO_INCREMENT, userName VARCHAR(100) NOT NULL,

flask中&#39;bool&#39; object has no attribute &#39;__call__&#39;问题

#写flask时报错 <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> <ul class="nav navbar-nav navbar-right"> {% if current_user.is_authenticated() %} <li><

解决Flask中文件操作出现UnicodeDecodeError UnicodeDecodeError: &#39;ascii&#39; codec can&#39;t decode byte 0xe6 in positio

写一个Flask应用的功能时需要读文件,文件内容含指定字符串的话(即有个if key in filecontent的比较)就把文件内容输出到页面,,结果报错UnicodeDecodeError,查阅Flask的文档却似乎讲Flask默认哪里都是utf8编码,可现在却出了个由于字符是utf8而不是ascii报的错 最后解决了 我灵机一点把filecontent解码一下,写成filecontent.decode('utf8'),就顺利的运行了 版权声明:本文为博主原创文章,未经博主允许不得转载. 解

使用thinkphp3.2中的验证码功能

为了网站的安全性,使用验证码技术是比较常见的,今天按照thinkphp3.2完全开发手册的例子试了一下(地址http://document.thinkphp.cn/manual_3_2.html#verify),总是报错,没法显示验证码,原因原来是在PHP.INI文件中没有打开GD库. 只要将配置文件PHP.INI中的extension=php_gd2.dll注释去掉就可以了(php_gd2.dll   GD 库图像函数库 GD2). 生成验证码 public function code() {

yii2中添加验证码的实现方法

本文实例讲述了yii2中添加验证码的实现方法.分享给大家供大家参考,具体如下: 首先,在模型中添加验证码字段: ? 1 2 3 public function rules(){ return ['verifyCode', 'captcha'], } 其次,可以在函数attributeLabels中添加前台页面中验证码的字段名称: ? 1 2 3 public function atrributeLabels(){ return ['verifyCode'=>'Verification Code'

servlet中生成验证码

在servlet中生成验证码 package login; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Random; import javax.servlet.Ser

Flask中处理依赖的技巧

Flask应用中通常会用工厂模式 来创建应用对象,这样方便配置和测试.现在我们就用实例来学习Flask的处理依赖 应用代码 # app/__init__.pyfrom flask import Flaskfrom flask_xxxext import Xxxfrom flask_yyyext import Yyy# ... 一些flask拓展xx = Xxx()yy = Yyy() def create_app(config=None): app = Flask(__name__) xx.in

Flask中全局变量的实现

我们都知道在Flask中g,request,session和request是作为全局对象来提供信息的,既然是全局的又如何保持线程安全呢,接下来我们就看看flask是如何做到这点的.在源码中的ctx.py中有AppContext和RequestContext两个类,他们分别管理应用上下文和请求上下文.两者的实现也差不多,这里我们看看AppContext的实现 class AppContext(object): """The application context binds a

FlASK中的endpoint问题

先贴一点有关的flask代码,时间有限,我慢慢扩充 以下是flask源码中app.py中add_url_rule的代码. 主要是view_func  -- endpoint -- url 之间的对应关系. flask中,view_func与url并不是直接对应的,是url先找到endpoint, 然后通过endpoint再去找到对应的view_func,一个endpoint只能对应于一个view_func,在注册add_url_rule的时候,如果不指定endpoint,那么endpoint就会