[英]Flask session not persisting, losing data on page refresh in SPA
编辑:我已经意识到 else 语句实际上甚至没有被调用,但是在页面刷新时,它将logged_in
值设置为 false。 else 语句中的 print 从不打印。 如果我不这样做,它是如何设置为 false 的?
我有一个由 Flask 提供服务的单页 React 应用程序,都在同一台服务器上。 我正在使用socket.io-client
在后端和前端之间进行通信。
登录后,前端加载用户数据就好了。 如果我刷新页面,我将注销并返回登录页面。 为什么 session 没有持续存在?
Flask session cookie 存在于 Chrome 中。 session cookie id 与浏览器中的 session cookie 匹配,即使在刷新和注销后,但后端返回用户未登录。
似乎 session cookie 在刷新时丢失了数据。
这是反应代码的片段:
const ENDPOINT = "http://127.0.0.3:5000";
const SocketContext = createContext(null);
const socket = io();
export function useIsLoggedIn() {
const navigate = useNavigate();
const [response, setResponse] = useState(data);
useEffect(() => {
socket.emit('join', setResponse);
}, []);
if (response.success) {
console.log("routing to dashboard...");
navigate("/app/dashboard");
}
return response;
}
export function useLogIn() {
const sendMessage = (channel, message) => {
socket.emit(channel, message);
};
return { sendMessage };
}
这是后端 python 代码的片段:
@socketio.on('join')
def on_connect(data):
try:
if 'logged_in' in session and session['logged_in']:
print('logged_in')
user_content = content.get_content(user=session['username'])
error = None
join_room(session['company'])
emit('sign_in', {'content': user_content, 'error': error, 'success': True}, room=session['company'])
else:
print('not_logged_in')
error = 'Invalid login credentials'
emit('sign_in', {'content': CONTENT, 'error': error, 'success': False})
except Exception as e:
print(traceback.format_exc())
# print(e)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
print('path', path)
try:
print('session logged_in', session['logged_in'])
except Exception as e:
print('failed not logged_in', e)
if 'logged_in' not in session:
print('set logged_in to False')
session['logged_in'] = False
session.permanent = True
resp = make_response(render_template('index.html'))
return resp
数周以来,我一直试图弄清楚为什么 session 会在刷新时重置并注销用户。 任何帮助表示赞赏,谢谢。
如果您需要使用 Flask,您应该尝试使用 Flask 库处理登录状态,在本例中为 flask_login。
我没有在这里提供所有详细信息,但我相信您至少需要以下内容才能使其正常工作:
在您的应用定义文件中:
from flask import Flask
from flask_login import LoginManager
login_manager = LoginManager()
def create_app():
"""App factory."""
app = Flask(__name__, instance_relative_config=True)
login_manager.init_app(app)
with app.app_context():
from my_app.views.view_users import view_users
from my_app.views.main_view import main_view
app.register_blueprint(view_users)
app.register_blueprint(main_view)
# Login manager config
login_manager.login_view = 'view_users.login'
接下来,您需要创建 view_users.py。 此文件应包含来自 flask_login package 的 login_user。
from flask import render_template, Blueprint, redirect, url_for
from flask_login import login_user
view_users = Blueprint('view_users', __name__)
@view_users.route('/login', methods=['GET', 'POST'])
def login():
"""Login the user."""
if password_matches(pass_db, passw): # you need to check the provided password - you will need a form and a html for it
login_user(user)
next = url_for('main_view.landing')
return redirect(next)
当然,您仍然需要为@login_manager.user_loader 和继承自flask_login.UserMixin 的User class 定义一个function。 请检查文档。
最后,在您的视图/路由/端点定义文件中,使用@login_required 装饰每个路由定义:
from flask_login import login_user, login_required, logout_user, current_user
from flask import render_template, Blueprint
main_view = Blueprint('main_view', __name__)
@main_view.route('/landing')
@login_required
def landing():
"""Landing page after user login."""
data = ['my data']
user_details = current_user # if you need any - this will come from your user_loader function
return render_template(
'landing.html',
data=data
)
@main_view.route('/a_end_point')
@login_required
def a_end_point():
"""Landing page after user login."""
user_details = current_user # if you need any - this will come from your user_loader function
data = ['my data']
return render_template(
'a_end_point.html',
data=data
)
祝你好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.