在校验的过程当中,我们分为前端校验和后端校验。
前端校验:使用前端js进行页面数据的校验,校验通过,再提交。优点:编写简单,缺点:安全性能不够。
@bule_print.route("/check/", methods=["GET", "POST"])
def check():
return render_template("front_end_check.html")
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="../static/dist/css/bootstrap.css">
<script src="../static/jquery.min.js/">script>
<script src="../static/dist/js/bootstrap.js">script>
head>
<body>
<form class="form form-horizontal container" onsubmit="return check()">
<br>
<div class="form-group">
<lable class="col-md-4 control-label">用户名:lable>
<div class="col-md-6">
<input class="form-control" name="username" id="username_check">
div>
div>
<div class="form-group">
<lable class="col-md-4 control-label">密码:lable>
<div class="col-md-6">
<input class="form-control" name="password">
div>
div>
<div class="form-group">
<input type="submit" class="btn btn-success pull-right">
div>
form>
<script>
function check() {
var user = $("#username_check").val();
var len = user.length;
if (len<6 || len>16){
alert("用户名长度不合法,字符在6~16之间");
return false
} else {
return true
}
}
script>
body>
html>
后端校验:就是当数据传递到后端视图进行校验,缺点:编写比较繁复,优点:安全性好。
后端校验可以直接在视图中编写,但太过复杂,所有采用flask-wtf
安装包
pip install flask-wtf
Wtf插件安装会安装两样东西:
一个表单定义类
一个表单字段定义类这两个类结合可以定义出一个对表单进行描述的类,
对表单描述的类可以直接在前端生成表单。
常用的表单字段:
校验规则:
在views同级目录创建form.py文件
# form.py
from flask_wtf import FlaskForm
import wtforms
from wtforms import validators
class RegisterForm(FlaskForm):
username = wtforms.StringField(
# 文本
label="用户名",
# 验证规则
validators=[
validators.Email(message="邮箱")
]
)
password = wtforms.PasswordField(
# 文本
label="密码",
# 验证规则
validators=[
validators.DataRequired(message="密码必填")
]
)
repassword = wtforms.PasswordField(
# 文本
label="重复输入密码",
# 验证规则
validators=[
validators.EqualTo("password", message="密码不一致")
]
)
# view.py
# 后端验证
@user_print.route('/register', methods=["GET", "POST"])
def register():
my_form = RegisterForm()
if request.method == "POST":
if my_form.validate_on_submit():
print("注册成功!")
else:
print(my_form.username.errors) # ['邮箱']
print(my_form.errors) # {'username': ['邮箱'], 'repassword': ['密码不一致']}
return render_template("register.html", **locals())
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<form action="/register" method="post">
{% for i in my_form %}
<p>{{ i.label }}:{{ i }}p>
{% endfor %}
<input type="submit">
form>
body>
html>
# form.py
from flask_wtf import FlaskForm
import wtforms
from wtforms import validators, ValidationError
def check_username(form, field):
"""
自定义校验:验证用户名不能包含敏感信息
:param form: 表单
:param form:字段
"""
print("当前字段的值:", field.data)
data_list = ["admin", "nb"]
# 判断
for data in data_list:
if field.data.find(data) != -1:
raise ValidationError("用户名不能包含敏感信息")
class RegisterForm(FlaskForm):
username = wtforms.StringField(
# 文本
label="用户名",
# 验证规则
validators=[
validators.Length(min=2, max=16, message="用户名长度在2-16之间"),
check_username
]
)
password = wtforms.PasswordField(
# 文本
label="密码",
# 验证规则
validators=[
validators.DataRequired(message="密码必填")
]
)
repassword = wtforms.PasswordField(
# 文本
label="重复输入密码",
# 验证规则
validators=[
validators.EqualTo("password", message="密码不一致")
]
)
# view.py
# 后端验证
@user_print.route('/register', methods=["GET", "POST"])
def register():
my_form = RegisterForm()
if request.method == "POST":
if my_form.validate_on_submit():
print("注册成功!")
else:
print(my_form.username.errors) # ['邮箱']
print(my_form.errors) # {'username': ['邮箱'], 'repassword': ['密码不一致']}
return render_template("register.html", **locals())
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<form action="/register" method="post">
{% for i in my_form %}
<p>{{ i.label }}:{{ i }}p>
{% endfor %}
<input type="submit">
form>
body>
html>
跨站点请求伪造(Cross-site request forgery),CSRF跨站请求伪造:使用当前浏览器还在生效状态的cookie对指定网站进行操作。最初针对的是银行网站的转账。
防御策略:csrf检验
在请求之初,Flask服务会给用户下发一个随机校验值,用户提交数据的时候,携带校验值,这个校验值每次刷新页面都不一样,没有或者错误的校验值,访问被拒绝。csrf检验只针对post请求有效,对get不检测
首先要保证前端的name和定义的校验表单字段一样
# 蓝图csrf配置
# 创建空的对象
db = SQLAlchemy()
csrf = CSRFProtect()
def create_app(obj):
"""
创建app函数
:param obj: 配置文件类
:return: goods
"""
app = Flask(__name__) # 创建app
app.config.from_object(obj) # app的配置类
# db与app关联
db.init_app(app)
# csrf与app关联
csrf.init_app(app)
# 该引用必须放在函数里面,不然会循环引用
from BluePrint.user import user_print
# 注册蓝图
app.register_blueprint(user_print)
return app
# 创建app
app = create_app(Develop)
在模板的form中,使用csrf_token方法获取csrftoken,并提交
from BluePrint import csrf
@csrf.exempt
@user_print.route('/aaa', methods=["POST"])
def aaa():
return "aaa"