Use Flask's g object and MySQL to implement user login and logout functions

In Flask, the g object is a special type of object called a "context global variable". It stores information for the lifetime of a request and can be accessed and shared throughout the request.
insert image description here
The g object is useful for storing user login information. For example, when a user is authenticated and logged in, you can store the user's identity in g.user for use in other parts of the current request. This way, in other functions, methods, or views of the request, you can easily access and verify the user's login status without repeating the verification in each function.

By storing the user's login information in the g object, you can ensure that the same user information is used throughout the processing of the request without repeatedly querying the database or passing the information to each function. This provides a convenient way to access and share request-scoped data, enabling you to easily handle functions such as user authentication and authorization.
Here's an example of how to use the object in Flask gto save, access user login information, and logout:

First, assume we have a UserModel table in a MySQL database and have created a SQLAlchemy model to interact with it.

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)

This code sets up the basic structure for the user model in the Flask application, including the user's ID, username, and password. SQLAlchemy will handle the mapping between Python classes and corresponding database tables, allowing you to perform database operations using UserModel classes.

User login and save login status

gThen we use the object and the hook function in the Flask application before_requestto save the user login information:

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}

The first function is decorated my_before_requestwith the decorator. @app.before_requestThat means it will be executed before every request. The purpose of this function is to check for the existence of the "user_id" key in the session and set the g"user" attribute of the global object according to the value of this key. Specifically, it gets the value of "user_id" from the session, then uses that value to query the UserModel table in the database, gets the corresponding user object, and sets that object to g.user. g.userSet to None if "user_id" does not exist or a corresponding user object is not found .

The second function is decorated my_context_processorwith the decorator. @app.context_processorThis means it will be registered as a context handler for setting global variables in templates. The function returns a dictionary where the key is "user" and the value is g.user. This way, when the template is rendered, the variable can be used in the template userto access the current user's information.

To summarize, what this code does is check the user ID in the session before each request, query the database for the user object, and set the user object as a global variable for use in the template. In this way, when rendering the template, the information of the current user can be easily obtained.

Then write the login implementation route

@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')

Log out

In Flask, you can logout a user by removing the user ID from the session. Here is an example of a simple logout route:

from flask import redirect, url_for

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

This logout route first removes the 'user_id' from the session. Then the route redirects to the home page.

user_idNote that you also need to make sure that after the user logs out, you can no longer pretend to be a logged out user by changing the browser's cookie. This is usually achieved by setting the session's secure attribute to True so that the cookie is only transmitted over HTTPS connections. At the same time, setting the httponly attribute of the session to True can prevent JavaScript from accessing the cookie, so as to avoid cross-site scripting (XSS) attacks.

Guess you like

Origin blog.csdn.net/qq_42076902/article/details/131300872