授课语音

Flask 表单处理与用户认证

在 Web 应用中,表单是与用户交互的重要方式之一。通过表单,用户可以提交数据(如注册、登录、更新信息等)。而用户认证是确保应用安全性和保护敏感数据的关键部分。Flask 提供了多种方式来处理表单和实现用户认证。

本课将介绍如何在 Flask 中处理表单,如何验证表单数据,以及如何实现基本的用户认证功能(如注册、登录、登出)。通过本课,您将掌握如何在 Flask 中实现表单处理和安全的用户认证。


1. Flask 表单处理

Flask 提供了许多方式来处理表单,但最常用的方式是通过 Flask-WTF 扩展。Flask-WTF 是一个集成了 WTForms 的 Flask 扩展,它提供了表单生成、表单验证和 CSRF 防护等功能。

1.1 安装 Flask-WTF

首先,安装 Flask-WTF:

pip install Flask-WTF

1.2 配置 CSRF 防护

CSRF(跨站请求伪造)是一种攻击方式,Flask-WTF 默认启用 CSRF 防护。您可以通过以下配置来启用或禁用 CSRF 防护:

app.config['SECRET_KEY'] = 'your_secret_key'
app.config['WTF_CSRF_SECRET_KEY'] = 'your_csrf_secret_key'

SECRET_KEY 用于加密会话和防止 CSRF 攻击。


2. 创建和处理表单

2.1 创建表单类

Flask-WTF 使用类来表示表单,每个字段是 wtforms 中的一个字段类型。以下是一个用户注册表单的示例:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Register')

2.2 代码解析

  • FlaskForm:Flask-WTF 表单基类。
  • StringFieldPasswordField:分别代表字符串和密码类型的输入字段。
  • validators:验证器,用于验证表单字段的有效性。
    • DataRequired:确保该字段不能为空。
    • Email:验证该字段是否为有效的电子邮件地址。
    • EqualTo('password'):确保 confirm_passwordpassword 字段的值一致。

2.3 渲染表单

在视图函数中,您可以使用 render_template 渲染表单。以下是一个显示注册表单并处理表单提交的视图函数:

from flask import render_template, url_for, flash, redirect
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'

db = SQLAlchemy(app)

# 用户模型类
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)

@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        hashed_password = generate_password_hash(form.password.data)
        user = User(username=form.username.data, email=form.email.data, password=hashed_password)
        db.session.add(user)
        db.session.commit()
        flash('Account created successfully!', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)

2.4 代码解析

  • form.validate_on_submit():检查表单是否通过了验证,并且请求方法为 POST
  • generate_password_hash:用于加密密码,增强安全性。
  • flash:显示成功消息(需要在模板中调用 get_flashed_messages())。

3. 用户认证 - 登录与登出

3.1 用户登录

用户登录过程通常包括验证用户名和密码是否正确。Flask 提供了通过会话管理用户认证状态的方式。以下是一个简单的登录功能实现:

from flask import session, flash

@app.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(username=username).first()

        if user and check_password_hash(user.password, password):
            session['user_id'] = user.id
            flash('Login successful!', 'success')
            return redirect(url_for('dashboard'))
        else:
            flash('Login failed. Check username and/or password', 'danger')

    return render_template('login.html')

3.2 代码解析

  • request.form:获取 POST 请求中表单提交的数据。
  • check_password_hash:用于比对密码的哈希值,确保输入的密码与存储的密码一致。
  • session['user_id']:存储用户 ID,以便在后续请求中跟踪用户登录状态。

3.3 用户登出

登出功能非常简单,您只需清除会话中的用户信息:

@app.route("/logout")
def logout():
    session.pop('user_id', None)
    flash('You have been logged out', 'success')
    return redirect(url_for('login'))

4. 模板渲染与表单展示

Flask-WTF 提供了直接在模板中渲染表单的功能。以下是一个简单的表单模板(register.html)示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</head>
<body>
    <h2>Register</h2>
    <form method="POST">
        {{ form.hidden_tag() }}
        <div>
            {{ form.username.label }} {{ form.username() }}
            {% for error in form.username.errors %}
                <span style="color: red;">{{ error }}</span>
            {% endfor %}
        </div>
        <div>
            {{ form.email.label }} {{ form.email() }}
            {% for error in form.email.errors %}
                <span style="color: red;">{{ error }}</span>
            {% endfor %}
        </div>
        <div>
            {{ form.password.label }} {{ form.password() }}
            {% for error in form.password.errors %}
                <span style="color: red;">{{ error }}</span>
            {% endfor %}
        </div>
        <div>
            {{ form.confirm_password.label }} {{ form.confirm_password() }}
            {% for error in form.confirm_password.errors %}
                <span style="color: red;">{{ error }}</span>
            {% endfor %}
        </div>
        <div>
            {{ form.submit() }}
        </div>
    </form>
</body>
</html>

5. 总结

通过本课的学习,您已经掌握了如何在 Flask 中处理表单,如何进行表单验证、如何使用 Flask-WTF 扩展来增强表单功能。同时,您也学会了如何实现基本的用户认证功能,包括注册、登录和登出操作。表单和认证是 Web 应用的基础功能,掌握这些内容将帮助您构建更完整、安全的 Web 应用。

去1:1私密咨询

系列课程: