Flask:用户可以访问其他用户会话

问题描述 投票:0回答:1

我用 Flask、Flask-login 和 FLask-sqlalchemy 建立了一个带有用户登录的小网站。

生产时:

  • 如果用户 A 自己登录,他将看到他的数据和视图,一切正常。
  • 然后,如果用户 B 同时从另一台设备连接到该网站,他也会看到用户 A 的会话(和数据)

需要注意的是,我对两个不同的服务器有相同的行为:pythonanywhere 和 O2switch。所以,问题应该在我这边:/(或者两台服务器的配置错误?)

在本地,我没有问题(很难在其他设备上达到与生产环境相同的条件,但假设我作为第二个用户使用浏览器的隐身模式时没有问题)。

我正在使用的代码:

__init__.py

# library
from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy

# modules
from mywebsite_flask.config import config_selection


# init extensions
db = SQLAlchemy()
login_manager = LoginManager()


# app set-up
def create_app(config_mode):
    app = Flask(__name__)
    app.config.from_object(config_selection[config_mode])

    # flask-login init
    login_manager.login_view = "auth_bp.login"
    login_manager.init_app(app)

    # database init
    db.init_app(app)
    from mywebsite_flask.auth.models import Customer
    with app.app_context():
        db.create_all()

    # add blueprints
    from mywebsite_flask.public.routes import public_bp
    app.register_blueprint(public_bp)
    from mywebsite_flask.auth.routes import auth_bp
    app.register_blueprint(auth_bp)

    app.app_context().push()

    return app

models.py

# library
from flask_login import UserMixin

# modules
from mywebsite_flask import db, login_manager


class Customer(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    email = db.Column(db.String, unique=True)
    password = db.Column(db.String)
    token_verification = db.Column(db.Boolean, default=False)

    def __repr__(self):
        return f"Customer #{self.id}:{self.email}>"


@login_manager.user_loader
def load_user(customer_id):  # customer found by unique id
    return Customer.query.get(int(customer_id))

auth.routes.py

# library
from flask import Blueprint, flash, redirect, render_template, request, url_for
from flask_login import current_user, login_required, login_user, logout_user
from werkzeug.security import generate_password_hash

# modules
from mywebsite_flask import db
from mywebsite_flask.auth.models import Customer


# init
auth_bp = Blueprint("auth_bp", __name__)


@auth_bp.route("/login", methods=("GET", "POST"))
def login():
    if not current_user.is_authenticated:
        if request.method == "POST":
            email = request.form.get("email").lower()
            password = request.form.get("password")
            remember = True if request.form.get("remember") else False

            check_user = db.session.execute(
                db.select(Customer).filter_by(email=email)
            ).scalar_one_or_none()

            if not various_check(check_user):
                # check that none of them are None
                error_msg = "Un des champs requis est vide."
                flash(error_msg, category="error")
            else:
                login_user(check_user, remember=remember)
                return redirect(url_for("public_bp.home"))

        return render_template("auth/login.html")

    else:
        return redirect(url_for("core_bp.customer_home"))


@auth_bp.route("/logout", methods=("GET", "POST"))
@login_required
def logout():
    logout_user()
    return redirect(url_for("public_bp.home"))


# end

我已经多次检查了我的代码,查看了 Flask-login 文档并阅读了一些类似的 stackoverflow 帖子,但无法找到解决方案。有人可能已经遇到这个问题或发现我的代码有问题吗?

编辑

根据要求,cookie:

请注意,当问题触发时:如果用户 B 在用户 A 登录后连接,我们会看到用户 A 的会话,但用户 B 端没有 cookie(但我们仍然可以看到并使用用户 A 会话) .

python flask flask-login
1个回答
0
投票

好的,我已经找到问题了。

init
.py 的应用程序工厂 create_app() 中,我有
app.app_context().push()

我忘记了我不久前将其添加为快捷方式。这是为了轻松访问应用程序中各处的 app.config 参数。

问题已解决:

  • 删除这个
    app.app_context().push()
  • 使用
    current_app
    (如果可能)或
    with app.app_context()
    (如果没有),访问app.config(我原来的需要)

app.app_context().push()
以某种方式干扰服务器上创建的不同会话(更具体地说,是来自 Flask 登录的
current_user

(感谢@relent95的帮助)

© www.soinside.com 2019 - 2024. All rights reserved.