python - Flask-Session 刷新后丢失 Flask-Login 会话数据
问题描述
我目前正在使用 Flask、Flask-Session、Flask-SocketIO 和 Flask-Login 构建具有不同房间的聊天应用程序。我将用户的当前房间保存在会话中,以便可以显示基于该房间的信息。我正在从 Flask-SocketIO 事件更新此会话数据,我只能通过使用 Flask-Session 模块而不是来自 Flask 的内置会话来做到这一点。因此,当我使用 Flask-Login 登录用户时,当前用户的数据将保存在此 Flask-Session 会话中,会话类型为“文件系统”。然后当我刷新页面时,Flask-Login 数据不再在会话中,这导致我的程序崩溃,因为当前用户现在是 AnonymousUserMixin 对象,因此用户已注销。那么是什么导致会话失去当前用户' 的数据?一起使用 Flask-Session 和 Flask-Login 有问题吗?还是我只是在配置上做错了什么?
这是刷新前后会话的外观:
前:
<FileSystemSession {'_permanent': True, 'csrf_token': 'cd2428d22717128228ea31b9182ac46766802839', 'current_room': 'Lobby', '_fresh': True, '_user_id': '1', '_id': '4825ca5a26d88cfc91bcb75ef854505f0d4cdc736affaac2fd3211fb6015b34490c6ec47ec7175dee531442ec8d3a1d5f092c4de1349ca0d48fe723aed678c5a', '_flashes': [('success', 'Logged in successfully')]}>
后:
<FileSystemSession {'_permanent': True, 'csrf_token': 'cd2428d22717128228ea31b9182ac46766802839', 'current_room': 'Lobby'}>
如您所见,来自 Flask-Login 模块的会话数据消失了,这就是它说没有用户登录的原因。
这是我的代码:
初始化.py:
from flask import Flask
from flask_session import Session
from flask_login import LoginManager
from .models import *
app = Flask(__name__)
def create_app():
app.config["SECRET_KEY"] = "secret!"
app.config["SESSION_TYPE"] = "filesystem"
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{DB_NAME}"
login_manager = LoginManager()
login_manager.init_app(app)
Session(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
db.init_app(app)
from .application import socketio
from .views import views
from .auth import auth
app.register_blueprint(views, url_prefix="/")
app.register_blueprint(auth, url_prefix="/")
return socketio, app
验证码:
from flask import Blueprint, render_template, flash, url_for, redirect, session, current_app
from flask_login import login_user, logout_user, current_user, login_required
from .wtform_fields import RegistrationForm, LoginForm
from werkzeug.security import generate_password_hash, check_password_hash
from .models import *
from app import app
auth = Blueprint("auth", __name__)
@auth.route("/login", methods=["GET", "POST"])
def login():
login_form = LoginForm()
if login_form.validate_on_submit():
username = login_form.username.data
password = login_form.password.data
user = User.query.filter_by(username=username).first()
if user:
if check_password_hash(user.password, password):
login_user(user)
flash("Logged in successfully", category="success")
session["current_room"] = "Lobby"
return redirect(url_for("views.chat"))
else:
flash("Password is incorrect", category="error")
else:
flash(f"No user named {username}", category="error")
return render_template("login.html", form=login_form, user=current_user)
视图.py:
from flask import Blueprint, render_template, flash, redirect, url_for, request, session
from flask_login import current_user, login_required
from .models import *
views = Blueprint("views", __name__)
@views.route("/chat", methods=["GET", "POST"])
def chat():
return render_template("chat.html", user=current_user, rooms=current_user.rooms, current_room=Room.query.filter_by(room_name=session["current_room"]).first())
#Crashes after refresh because current user is anonymous
应用程序.py
from flask import session
from flask_socketio import SocketIO, emit, send, join_room, leave_room
from app import app
from flask_login import current_user, logout_user
socketio = SocketIO(app, manage_session=False)
@socketio.on('join')
def on_join(data):
user = data["username"]
room = data["room"]
join_room(room)
session["current_room"] = room #Where I update the session
emit("room-manager", {"message": f"{user} has joined the {room} room"}, room=room)
解决方案
推荐阅读
- c# - Xamarin 选项卡式页面 MVVM 在页面之间传递数据
- azure - 在 Blazor 应用程序上下载 JS 和 CSS 文件时的性能问题,即使它们被缓存
- javascript - 如何在 typescript 构造函数运行之前设置一个属性
- codeigniter-4 - Codeigniter 4将插入的ID从第一个表保存到第二个表中
- java - HttpsURLConnection:连接超时
- excel - 将数据从一张表复制到另一张表,状态为已更新
- .net-core - Aspose PDF 错误:“Gdip”在 Mac OSX 上使用 Dotnet Core 3.x 应用程序引发异常
- google-colaboratory - Tensorflow 2 对象检测 API 低 mAP
- javascript - 无法监视导入的类函数
- python - Python3:如何为 cx_oracle 连续插入语句流转义特殊字符(ORA-01756:引用的字符串未正确终止)