带有认证功能的模块化 Flask 应用程序

Beginner

This tutorial is from open-source community. Access the source code

简介

在本实验中,我们将逐步介绍如何创建和使用 Flask 蓝图,以便通过视图来构建你的应用程序。Flask 蓝图允许你将相关的视图、代码和资源组合在一起,使你的应用程序具有模块化和可扩展性。我们将创建一个简单的应用程序,其中将包括用户认证和博客文章功能。

注意:你需要自己创建代码文件并在环境中运行它。你可以在 Web 5000 上预览 Flask 服务状态。

创建一个蓝图

让我们从为我们的应用程序创建一个蓝图开始。这个蓝图将被命名为“auth”,并将处理与用户认证相关的视图。我们将在一个名为flaskr/auth.py的单独模块中定义我们的蓝图。

## flaskr/auth.py

import functools
from flask import Blueprint, flash, g, redirect, render_template, request, session, url_for
from werkzeug.security import check_password_hash, generate_password_hash
from flaskr.db import get_db

## 创建一个名为“auth”的蓝图
bp = Blueprint('auth', __name__, url_prefix='/auth')

注册蓝图

创建蓝图后,我们需要将其注册到我们的应用程序中。这在flaskr/__init__.py中的应用程序工厂函数中完成。

## flaskr/__init__.py

def create_app():
    app =...
    ## 省略现有代码

    ## 导入并注册蓝图
    from. import auth
    app.register_blueprint(auth.bp)

    return app

实现注册视图

现在,让我们在flaskr/auth.py中实现注册视图。此视图将呈现一个注册表单并处理表单提交。

## flaskr/auth.py

@bp.route('/register', methods=('GET', 'POST'))
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        error = None

        if not username:
            error = '用户名是必填项。'
        elif not password:
            error = '密码是必填项。'

        if error is None:
            try:
                db.execute(
                    "INSERT INTO user (username, password) VALUES (?,?)",
                    (username, generate_password_hash(password)),
                )
                db.commit()
            except db.IntegrityError:
                error = f"用户 {username} 已注册。"
            else:
                return redirect(url_for("auth.login"))

        flash(error)

    return render_template('auth/register.html')

实现登录视图

接下来,我们将在flaskr/auth.py中实现登录视图。此视图将处理用户登录功能。

## flaskr/auth.py

@bp.route('/login', methods=('GET', 'POST'))
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        error = None
        user = db.execute(
            'SELECT * FROM user WHERE username =?', (username,)
        ).fetchone()

        if user is None:
            error = '用户名错误。'
        elif not check_password_hash(user['password'], password):
            error = '密码错误。'

        if error is None:
            session.clear()
            session['user_id'] = user['id']
            return redirect(url_for('index'))

        flash(error)

    return render_template('auth/login.html')

实现登出视图

现在让我们在flaskr/auth.py中添加一个登出视图。此视图将处理用户登出功能。

## flaskr/auth.py

@bp.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))

实现登录_required 装饰器

我们还需要一个装饰器来保护那些需要用户登录的视图。这个装饰器将在flaskr/auth.py中实现。

## flaskr/auth.py

def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('auth.login'))

        return view(**kwargs)

    return wrapped_view

总结

在这个实验中,我们学习了如何使用 Flask 蓝图来构建我们的应用程序。我们创建了一个用于用户认证的蓝图,并实现了注册、登录和登出视图。我们还实现了一个装饰器来保护那些需要用户登录的视图。有了这些知识,你现在可以以模块化和可扩展的方式构建你的 Flask 应用程序了。