一、WTF表单:
1.web表单:
Web 表单是 Web 应用程序的基本功能。默认开启CSRF保护功能
它是HTML页面中负责数据采集的部件。表单有三个部分组成:表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器。
在Flask中,为了处理web表单,我们可以使用 Flask-WTF 扩展,它封装了 WTForms,并且它有验证表单数据的功能。
2.WTForms支持的HTML标准字段:
字段对象 | 说明 |
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PassWordField | 密码文本字段 |
HiddenField | 隐藏文本字段 |
DateField | 文本字段,值为datetime.date文本格式 |
DateTimeField | 文本字段,值为datetime.datetime文本格式 |
InterField | 文本字段,值为整数 |
DecimalField | 文本字段,值为decimal.Decimal |
FloatField | 文本字段,值为浮点数 |
BooleanField | 复选框,值为True和False |
RadioField | 一组单选框 |
SelectField | 下拉列表 |
SelectMutipleField | 下拉列表,可选择多值 |
FileField | 文件上传字段 |
SubmitField | 表单体检按钮 |
FormField | 把表单作为字段嵌入到另一个表单 |
FieldList | 一组指定类型的字段 |
3.WTForm常用验证函数:
验证函数 | 说明 |
DataRequired | 确保字段中有数据 |
EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
Length | 验证输入的字符串长度 |
NumberRange | 验证输入的值在数字范围内 |
URL | 验证URL |
AnyOf | 验证输入值在可选列表中 |
NoneOf | 验证输入值不在可选列表中 |
4.WTForm的代码演示:
视图函数:
导入模块:
from flask import Flask,render_template, request, flash
# 导入flask_etf扩展包提供的表单类
from flask_wtf import FlaskForm
# 导入wtf提供的字段
from wtforms import StringField, PasswordField, SubmitField
# 导入wtf扩展提供的验证函数
from wtforms.validators import DataRequired, EqualTo
创建实例, 设置秘钥值
app = Flask(__name__)
# 设置秘钥,对提交的表单数据进行加密
app.config['SECRET_KEY'] = "ilovepython"
创建表单类:
# 自定义表单类:实现注册的表单,文本框、密码、确认密码、提交
class Form(FlaskForm):
usr = StringField("用户名", validators=[DataRequired("请填写用户名")])
pswd = PasswordField("密码", validators=[DataRequired("请填写密码")])
pswd2 = PasswordField("确认密码", validators=[DataRequired("请填写确认密码"), EqualTo("pswd")])
submit = SubmitField("提交")
创建视图函数:
# 定义是视图函数
@app.route("/demo01", methods=["GET", "POST"])
def demo02():
form = Form()
if form.validate_on_submit():
# 获取表单提交的数据
usr = form.usr.data
pswd = form.pswd.data
pswd2 = form.pswd2.data
print("usr:" + str(form.usr))
# 假装提交成功
print(usr, pswd, pswd2)
print(form.validate_on_submit())
print(form.validate_on_submit())
return render_template("demo01_wtf.html", form = form)
启动程序
if __name__ == '__main__':
app.run(debug=True)
表单模板文件.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ request.method }}</title>
</head>
<body>
{# 注册页面 #}
<form method="post">
{{ form.csrf_token }}
<p>{{ form.usr.label }}: {{ form.usr }}</p>
<p>{{ form.pswd.label }}: {{ form.pswd }}</p>
<p>{{ form.pswd2.label }}:{{ form.pswd2 }}</p>
<p>{{ form.submit }}</p>
</form>
</body>
</html>
三、 CSRF跨站请求伪造(二):
1.跨站请求伪造的流程:
1.1 跨站请求伪造的过程:
a.用户登录正常的网站;
b.网站将cookie写入服务器,实现状态保持;
c.用户在未登出时,访问了恶意的钓鱼网站;
d.用户在主观未知的情况下, 像正常网站发送了恶意网站伪造实现的请求;
2 .问题:
- a.攻击正常网站的请求是用户发起的
- b.恶意网站如何获取正常网站的信息:
-
- 钓鱼:谁咬钩钓谁
3 .跨站请求防护的实现:
csrf_token是一个随机数,令牌,每次请求都会生成一个新的值;
1.后端服务器首先需要开启csrf保护,会验证post/put/delete/patch请求, 一般不会验证ge请求;
2.后端生成csrf_token, 会存入浏览器的cookie中,其次会存入表单中;
3.用户请求,cookie中的csrf_token会自动携带,后端比较cookie找那个的csrf_tokrn好人表中的是否一致;
4.如果不一致,请求则为假.
4.模拟CSRF跨站伪造请求攻击:
三、模板中特有的变量和函数
-
config
你可以从模板中直接访问Flask当前的config对象:{{config.SQLALCHEMY_DATABASE_URI}} sqlite:///database.db
-
request
就是flask中代表当前请求的request对象:{{request.url}} http://127.0.0.1
-
session
为Flask的session对象{{session.new}} True
-
g变量
在视图函数中设置g变量的 name 属性的值,然后在模板中直接可以取出{{ g.name }}
-
url_for()
url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接:{{url_for('home')}} /
如果我们定义的路由URL是带有参数的,则可以把它们作为关键字参数传入url_for(),Flask会把他们填充进最终生成的URL中:
{{ url_for('post', post_id=1)}}
/post/1
- get_flashed_messages()
这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉:
{%for message in get_flashed_messages()%}
{{message}}
{%endfor%}