21 - form表单验证 和 csrf跨站请求伪造

一. Form 表单验证

        (1). 官网:      

https://wtforms.readthedocs.io/en/2.3.x/

        (2). 安装第三方库

pip install Flask-WTF

         (3). form类型和校验 

# Field类型:
    StringField  # 字符串
    PasswordField # 密码
    IntegerField # 整形
    DecimalField # 浮点,可以指定小数点位数
    FloatField # 浮点
    BooleanField # 布尔
    RadioField # 单选
    SelectField # 下拉列表
    DatetimeField # 日期
    ....
 
# 验证:
    DataRequired # 必填
    EqualTo  # 和谁保持一致
    IPAddress # 验证ip地址
    Length # 长度
    NumberRange # 数字范围
    URL # 必须符合路径格式
    Email # 邮箱
    Regexp # 正则

 

二. csrf跨站请求伪造

        (1). settings.py 设置随机字符串

SECRET_KEY = "HAJSDLASDNADALK" # 随机字符串

        (2). app.py 全局使用csrf保护

csrf = CSRFProtect(app=app)

三. 代码示例

        (1). 新建form.py 文件,定义 form 表单数据
import re

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length, ValidationError, EqualTo, Regexp


class UserForm(FlaskForm):
    # StringField:text文本框  ;DataRequired():必填 ;Length():长度; EqualTo():和谁保持一致
    name = StringField(label='用户名', validators=[DataRequired(), Length(min=6, max=12, message="用户名长度必须在6~12位之间")])
    password = PasswordField(label="密码", validators=[DataRequired(), Length(min=6, max=12, message="密码长度必须在6~12位之间")])
    confirm_pwd = PasswordField(label="确认密码",
                                validators=[DataRequired(), Length(min=6, max=12, message="密码长度必须在6~12位之间"),
                                            EqualTo('password', "两次密码不一致")])

    phone = StringField(label="手机号码", validators=[DataRequired(), Length(min=11, max=11, message="手机号码必须11位长度")])

    # 定义钩子方法,对用户名增加校验:validate_字段名
    def validate_name(self, data):
        if self.name.data[0].isdigit():
            raise ValidationError("用户名不能以数字开头")

    def validate_phone(self, data):
        phone = data.data
        if not re.search(r'^1[35678]\d{9}$', phone):
            raise ValidationError("手机号码格式错误")
        (2). view.py 调用表单对象,返回给前端
from flask import Blueprint, render_template
from util.form import UserForm

user_bp = Blueprint('user', __name__)


@user_bp.route('/',methods=["GET","POST"])
def hello_world():
    uform = UserForm()  # 表单类对象
    if uform.validate_on_submit():  # 主要通过validate_on_submit 进行校验
        print(uform.name)
        print(uform.password)
        return "提交成功"
    return render_template("user/index.html", uform=uform)
        (3). 前端使用表单对象定义form表单, post请求必须定义csrf_token
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户页面</title>
    <style>
        p span {
            font-size: 14px;
            color: red;
        }
    </style>
</head>
<body>
<form action="{{ url_for('user.hello_world') }}" method="post" novalidate>
    {#  post提交.必须定义 csrf_token 这句代码  #}
    {{ uform.csrf_token }}
    <p>
        {# form中定义的 label : 输入框 #}
        {{ uform.name.label }}:{{ uform.name }}
        <span>{% if uform.name.errors %}{{ uform.name.errors.0 }}{% endif %}</span>
    </p>
    <p>
        {{ uform.password.label }}:{{ uform.password }}
        <span>{% if uform.password.errors %}{{ uform.password.errors.0 }}{% endif %}</span>
    </p>

    <p>
        {{ uform.confirm_pwd.label }}:{{ uform.confirm_pwd }}
        <span>{% if uform.confirm_pwd.errors %}{{ uform.confirm_pwd.errors.0 }}{% endif %}</span>
    </p>

    <p>
        {{ uform.phone.label }}:{{ uform.phone }}
        <span>{% if uform.phone.errors %}{{ uform.phone.errors.0 }}{% endif %}</span>
    </p>
    <p><input type="submit" value="提交"></p>
</form>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值