圖片檢驗碼, 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',