Flask-Form表单的使用及其csrf_token的开启使用(六)

本文详细介绍了如何在Flask项目中使用Flask-WTF插件创建和使用表单,包括安装步骤、常用字段及校验方法,以及如何启用和自定义CSRF保护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Django 当中有form类,这个类给开发者提供了相当丰富的校验方式。
Flask和django同样推出了form类的插件,flask-wtf

一、flask form表单的安装和简单字段属性的应用

1、安装flask form插件

pip install flask-wtf

在这里插入图片描述
在这里插入图片描述

2、flask项目主目录下创建forms.py文件
在这里插入图片描述

3、表单常用的字段

字段说明
StringField字符串
IntegerField整型
TextAreaField文本
PasswordField密码
HiddenField隐藏域
DateFieldDatatime.data格式 年月日
DateTimeFieldDatatime.datatime 格式 年月日 时分秒
FloatField小数
RadioField单选
SelectField下拉
FileField文件
SubmitField提交

表单常用的校验

校验参数说明
Email邮件校验
EqualTo比较两个字段的值,常用于密码比较
IPAddressIpv4格式的IP地址
Length长度
NumberRange数字范围
DataRequired空值检查
Url验证是否符合url格式
AnyOf确保输入值在指定范围
NoneOf确保输入的值不在范围

4、在forms.py文件中导入form表单相关模块,并定义一个Form类

import wtforms # 定义字段
from flask_wtf import FlaskForm # 定义表单
from wtforms import validators # 定义校验
from FlaskStudent.models import Course

course_list = [(c.id,c.name) for c in Course.query.all()]

class TeacherForm(FlaskForm):
    """
    form字段的参数
    label=None, 表单的标签
    validators=None, 校验,传入校验的方法
    filters=tuple(), 过滤
    description='',  描述
    id=None, html id
    default=None, 默认值
    widget=None, HTML样式
    render_kw=None, HTML属性 参数
    """

    name = wtforms.StringField(
        label="教师姓名",
        render_kw={
            "class": "form-control",
            "placeholder": "教师姓名"
        },
        validators=[
            validators.DataRequired("姓名不可以为空")
        ]
    )
    age = wtforms.IntegerField(
        label="教师年龄",
        render_kw={
            "class": "form-control",
            "placeholder": "教师年龄"
        },
        validators=[
            validators.DataRequired("年龄不可以为空")
        ]
    )
    gender = wtforms.SelectField(
        label="教师性别",
        render_kw={
            "class": "form-control",
        },
        choices=[
            ("1","男"),
            ("2","女")
        ]
    )
    course = wtforms.SelectField(
        label="学科",
        render_kw={
            "class": "form-control",
        },
        choices=course_list
    )
    submit = wtforms.SubmitField(
        label="提交",
        render_kw={
            "class": "btn btn-primary btn-block",
        },
    )

5、视图路由文件中定义一个视图函数,并实例化表单,用于前端渲染

@app.route("/add_teacher/",methods=["GET","POST"])
def add_teacher():
    teacher_form = TeacherForm()
    return render_template("add_teacher.html",**locals())

6、前端页面,使用变量渲染form类中的字段
在这里插入图片描述
7、页面效果
在这里插入图片描述

二、flask form 中csrf_token 的使用

flask-wtf模块是携带csrf校验的,只是需要开启。在flask form中默认csrf_token 是没有开启的,需要我们手动去启动form表单的csrf_token。

csrf是针对于post请求的跨域限制,对get请求是没有作用的。

1、首先更改form表单的请求方式为post
在这里插入图片描述

2、首先在项目起始位置开启CSRFProtect,也就是main.py

这里注意由于版本问题,现在可以使用csrfProtect,之前版本会更新到CSRFProtect,所以我们现在索性就直接使用CSRFProtect,避免之后出现问题

导入CSRFProtect模块,关联flask应用
在这里插入图片描述

import pymysql
from flask import Flask
from flask import session
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import CSRFProtect # 导入csrf校验模块,csrfProtect在1.0之后移除

pymysql.install_as_MySQLdb()

app = Flask(__name__)

# 关联csrf和flask应用
csrf = CSRFProtect(app)
# 使用类配置加载
app.config.from_object('config.DebugConfig')


# 关联sqlalchemy和flask应用
db = SQLAlchemy(app)

3、然后在前端使用csrf_token就可以了

这里是根据form表单实例去使用csrf_token的

在这里插入图片描述

如果不配置这句话,而程序入口已经开启了应用的CSRF校验,则会在表单提交时报错

在这里插入图片描述

4、前端页面上打开开发者调试模式,查看csrf_token是否已经生成在隐藏域中
在这里插入图片描述

这里注意:

Django中的csrf_token的name名为middlewarecsrftoken
Flask中的csrf_token的name名为csrf_token

三、临时关闭csrf校验

有时候我们有一些功能虽然用的是post请求,但是又不想进行csrf校验,同时其他的一些功能视图还是需要用csrf校验的,这个时候就需要用到csrf内置的功能,临时关闭保护。

针对于指定的单个视图取消csrf的保护

在不需要保护的路由上方加上这句话:
@csrf.exempt

前提是开启CSRF时需要将CSRFProtect使用一个csrf变量实例化

在这里插入图片描述

然后在视图中导入main.py中应用的csrf对象
在这里插入图片描述

最后在不需要保护的视图路由上方加上这句话

这个时候哪怕是程序入口开启了csrf,还有前端页面页使用了表单实例的csrf_token,但是这时候是不会进行csrf的校验的
在这里插入图片描述

from flask import request
from flask import redirect

from flask import render_template
from FlaskStudent.main import app
from FlaskStudent.models import *
from FlaskStudent.main import csrf
from FlaskStudent.main import session
from FlaskStudent.forms import TeacherForm

@csrf.exempt # 临时关闭csrf校验
@app.route("/add_teacher/",methods=["GET","POST"])
def add_teacher():
    teacher_form = TeacherForm()
    return render_template("add_teacher.html",**locals())

四、定义csrf错误页面

就是在form表单提交,csrf校验失败(不通过)的情况下,不进行下面的报错
在这里插入图片描述

而是跳转到指定的错误提示页面。

这里我们需要新建一个错误提示页面:命名为csrf_403.html

{% extends "blank.html" %}

{% block label %}
    403 error
{% endblock %}

{% block container %}
    <div class="text-center">
        <div class="error mx-auto" data-text="403">403</div>
        <p class="lead text-gray-800 mb-5">csrf_token error</p>
        <p class="text-gray-500 mb-0">please check your settings or form,csrf_token is missing ! </p>
    </div>
{% endblock %}

再定义一个csrf_403的路由视图,用于发生校验错误跳转
这里必须传递一个参数reason,也不需要使用它或是返回它。如果不传递,csrf内置代码就识别不了,会报错。

# csrf 如果没有配置跳转的错误页面
# @csrf.error_handler
@app.route("/csrf_403/")
def csrf_tonken_error(reason):
    return render_template("csrf_403.html")

视图路由定义完了,再跟关闭csrf保护一样,在路由上方添加一个装饰器

@csrf.error_handler

添加这句话之后,只要前端提交表单时csrf校验失败,就是跳转到该路由视图指定的页面(该方法使用于所有csrf校验失败的视图)

from flask import request
from flask import redirect

from flask import render_template
from FlaskStudent.main import app
from FlaskStudent.models import *
from FlaskStudent.main import csrf
from FlaskStudent.main import session
from FlaskStudent.forms import TeacherForm

@csrf.exempt # 临时关闭csrf校验
@app.route("/add_teacher/",methods=["GET","POST"])
def add_teacher():
    teacher_form = TeacherForm()
    return render_template("add_teacher.html",**locals())

# csrf 如果没有配置跳转的错误页面
@csrf.error_handler # csrf错误跳转
@app.route("/csrf_403/")
def csrf_tonken_error(reason):
    return render_template("csrf_403.html")

效果:

我现在将add_teacher.html页面上的csrf变量注释掉

在这里插入图片描述
这个时候提交表单

在这里插入图片描述

就会跳转的定义的403页面

在这里插入图片描述

<think>好的,我现在需要帮助用户解决如何在Python中导入并使用extract_csrf_token的问题。首先,我需要确认用户提到的extract_csrf_token是什么库或框架中的函数。因为用户提供的引用链接中提到了异步IO和Express的配置,这可能涉及到不同的上下文,比如Python的某个web框架或者第三方库。 首先,我应该回忆常见的Python web框架,比如Django、Flask、Requests等,是否有内置的extract_csrf_token函数。例如,Django有处理CSRF令牌的内置方法,但通常是通过模板标签或中间件,而不是直接调用一个函数。Flask中可能使用Werkzeug的相关函数,但同样,可能不是直接名为extract_csrf_token。 接下来,用户可能引用了某个外部库或自定义函数。比如,可能来自某个第三方包,如requests-html或者其他处理HTML解析的库。也有可能用户参考的教程或文章中提到了自定义的提取方法,比如从HTML表单中解析CSRF令牌的值。 这时候,我需要检查用户提供的引用链接。引用[1]是关于Python异步IO的,可能不相关。引用[2]是关于Express的SSL配置,属于Node.js,所以可能与Python无关。因此,用户可能误引用了这些资料,或者这些引用与当前问题无关,需要用户进一步澄清。 假设用户没有提供正确的引用,我需要基于常见的Python库给出建议。例如,使用BeautifulSoup或lxml来解析HTML并提取CSRF令牌。或者,如果使用Flask-WTF扩展,可以通过表单中的csrf_token字段获取。 另外,可能存在一个名为extract_csrf_token的自定义函数,用户需要导入它。这时候需要确认该函数所在的模块路径,比如是否在项目中的某个文件中,或者是否来自某个安装的包。 因此,回答需要涵盖两种情况:使用第三方库中的函数,或者自定义函数。同时,提醒用户检查是否正确安装了相关库,或者是否正确引用了自定义模块。 最后,需要确保回答结构清晰,步骤明确,并生成相关问题以帮助用户深入理解。</think>在Python中使用`extract_csrf_token`需要根据具体场景选择实现方式。以下是两种典型场景的解决方案: ### 一、使用Web框架内置方法(推荐) 在Flask框架中,CSRF令牌可通过`Werkzeug`的安全模块获取: ```python from werkzeug.security import generate_csrf # 生成CSRF令牌 csrf_token = generate_csrf() ``` 在模板中通过表单标签调用: ```html <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> ``` ### 二、自定义HTML解析方法 使用`BeautifulSoup`解析HTML并提取CSRF令牌: ```python from bs4 import BeautifulSoup def extract_csrf_token(html_content): soup = BeautifulSoup(html_content, 'html.parser') csrf_input = soup.find('input', {'name': 'csrf_token'}) return csrf_input['value'] if csrf_input else None # 使用示例 with open('form.html') as f: print(extract_csrf_token(f.read())) ``` ### 三、第三方库集成 若使用`requests-html`库处理动态页面: ```python from requests_html import HTMLSession session = HTMLSession() response = session.get('http://example.com/login') csrf_token = response.html.find('input[name=csrf_token]', first=True).attrs['value'] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孜孜孜孜不倦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值