Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Flask会话未持久化,SPA页面刷新时丢失数据_Javascript_Python_Reactjs_Flask_Socket.io - Fatal编程技术网

Javascript Flask会话未持久化,SPA页面刷新时丢失数据

Javascript Flask会话未持久化,SPA页面刷新时丢失数据,javascript,python,reactjs,flask,socket.io,Javascript,Python,Reactjs,Flask,Socket.io,编辑:我意识到else语句实际上甚至没有被调用,但在页面刷新时,它将logged\u in值设置为false。else语句中的打印永远不会打印。如果我不这么做,它怎么会设置为false 我有一个由Flask提供服务的单页React应用程序,都在同一台服务器上。我正在使用socket.io客户端在后端和前端之间进行通信 登录后,前端会很好地加载用户数据。如果我刷新页面,我将注销并发送回登录页面。为什么会议没有持续下去 烧瓶会话cookie存在于Chrome中。即使在刷新和注销后,会话cookie

编辑:我意识到else语句实际上甚至没有被调用,但在页面刷新时,它将
logged\u in
值设置为false。else语句中的打印永远不会打印。如果我不这么做,它怎么会设置为false

我有一个由Flask提供服务的单页React应用程序,都在同一台服务器上。我正在使用
socket.io客户端
在后端和前端之间进行通信

登录后,前端会很好地加载用户数据。如果我刷新页面,我将注销并发送回登录页面。为什么会议没有持续下去

烧瓶会话cookie存在于Chrome中。即使在刷新和注销后,会话cookie id也与浏览器中的会话cookie匹配,但后端返回用户未登录

会话cookie似乎在刷新时丢失了数据

下面是react代码的一个片段:

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

@socketio.on('join')
def接通(数据):
尝试:
如果会话中的“登录”和会话[“登录”]:
打印(“已登录”)
用户内容=内容。获取内容(用户=会话['username'])
错误=无
加入会议室(会议[“公司])
emit('sign_in',{'content':user_content,'error':error,'success':True},room=session['company'])
其他:
打印(“未登录”)
错误='无效的登录凭据'
emit('sign_in',{'content':content,'error':error,'success':False})
例外情况除外,如e:
打印(traceback.format_exc())
#打印(e)
@app.route('/',默认值={'path':''})
@应用程序路径(“/”)
def catch_all(路径):
打印('路径',路径)
尝试:
打印('session logged_in',session['logged_in']))
例外情况除外,如e:
打印('failed not logged_in',e)
如果“登录”不在会话中:
打印('将登录设置为False')
会话['logged_in']=False
session.permanent=True
resp=make_response(呈现模板('index.html'))
返回响应

几周来,我一直在试图弄清楚为什么会话会重置,并在刷新时将用户注销。非常感谢您的帮助。

如果您需要使用Flask,您应该尝试使用Flask库处理登录状态,在本例中为Flask\u登录

我并没有在这里给出所有细节,但我相信您至少需要以下几点才能使其正常工作:

在应用程序定义文件中:

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_登录包中的登录用户

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\u manager.user\u loader和从flask\u login.UserMixin继承的用户类定义一个函数。请检查一下文件

最后,在视图/路由/端点定义文件上,用@login\u 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
        )

祝你好运

最后,我去掉了两边的socket.io,只在前端执行获取请求,并在后端执行app.routes。现在登录保持一致。并使用上下文提供程序而不是自定义挂钩来处理数据,而无需钻取