使用 Flask 的g对象和 MySQL 实现用户登录和注销功能

在Flask中,g对象是一个特殊类型的对象,被称为"上下文全局变量"。它在一次请求的生命周期内存储信息,并且可以在整个请求过程中访问和共享。
在这里插入图片描述
g对象对于存储用户登录信息非常有用。例如,当用户通过验证登录时,您可以将用户的身份信息存储在g.user中,以便在当前请求的其他部分使用。这样,在请求的其他函数、方法或视图中,您可以轻松地访问和验证用户的登录状态,而无需在每个函数中重复验证。

通过在g对象中存储用户的登录信息,您可以确保在请求的整个处理过程中使用相同的用户信息,而无需重复查询数据库或将信息传递给每个函数。这提供了一种方便的方式来访问和共享请求范围的数据,使您能够轻松地处理用户身份验证和授权等功能。
下面是如何在 Flask 中使用 g 对象来保存、访问用户登录信息以及注销登录的示例代码:

首先,假设我们有一个 UserModel 表在 MySQL 数据库中,且已经建立了一个 SQLAlchemy 模型来与之交互。

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class UserModel(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, nullable=False)
    password = db.Column(db.String(128), nullable=False)

该代码为Flask应用程序中的用户模型设置了基本结构,包括用户的ID、用户名和密码。SQLAlchemy将处理Python类与相应数据库表之间的映射,允许您使用UserModel类执行数据库操作。

用户登录并保存登录状态

接着我们在 Flask 应用中使用 g 对象和 before_request 钩子函数来保存用户登录信息:

from flask import Flask, g, session, abort
from flask_login import LoginManager, login_user
from flask_migrate import Migrate

# 初始化 Flask 应用
app = Flask(__name__)

# 初始化
migrate = Migrate(app, db)
db.init_app(app)

@app.before_request
def my_before_request():
    user_id = session.get("user_id")
    if user_id:
        user = UserModel.query.get(user_id)
        setattr(g, "user", user)
    else:
        setattr(g, "user", None)


@app.context_processor
def my_context_processor():
    return {
    
    "user": g.user}

第一个函数 my_before_request 使用 @app.before_request 装饰器进行修饰。这意味着它将在每次请求之前执行。该函数的目的是在会话中检查是否存在 “user_id” 键,并根据该键的值来设置全局对象 g 的 “user” 属性。具体来说,它从会话中获取 “user_id” 的值,然后使用该值查询数据库中的 UserModel 表,获取对应的用户对象,并将该对象设置为 g.user。如果 “user_id” 不存在或对应的用户对象未找到,则将 g.user 设置为 None。

第二个函数 my_context_processor 使用 @app.context_processor 装饰器进行修饰。这意味着它将注册为一个上下文处理器,用于在模板中设置全局变量。该函数返回一个字典,其中键为 “user”,值为 g.user。这样,在渲染模板时,就可以在模板中使用 user 变量来访问当前用户的信息。

总结起来,这段代码的作用是在每次请求之前检查会话中的用户ID,查询数据库获取用户对象,并将用户对象设置为全局变量,以便在模板中使用。这样,在渲染模板时,就可以方便地获取当前用户的信息。

然后写登录的实现路由

@app.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template("login.html")
    else:
        username = form.username.data
        password = form.password.data
        #表单登录验证
        user = UserModel.query.filter_by(username=username).first()
        if not user:
            return redirect(url_for("auth.login"))
        if user.password==password:
            session['user_id'] = user.id
            #添加user_id到session中
            return redirect("/")
        else:
            return render_template('pwd_error.html')

退出登录状态

在 Flask 中,你可以通过从 session 中删除用户 ID 来实现用户的注销。下面是一个简单的注销路由的示例:

from flask import redirect, url_for

@app.route("/logout")
def logout():
    session.clear()
    return redirect("/")

这个注销路由首先从 session 中删除了 ‘user_id’。然后路由重定向到了首页。

注意,你还需要确保在用户登出后,不能再通过更改浏览器的 user_id cookie 来伪装为已注销的用户。这通常通过将 session 的 secure 属性设置为 True 来实现,这样 cookie 就只能在 HTTPS 连接中传输。同时,将 session 的 httponly 属性设置为 True 可以阻止 JavaScript 访问到 cookie,这样可以避免跨站脚本(XSS)攻击。

猜你喜欢

转载自blog.csdn.net/qq_42076902/article/details/131300872