烧瓶会话不保留数据 [英] Flask session don't persist data

查看:44
本文介绍了烧瓶会话不保留数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Javascript应用程序和一个Flask应用程序.当用户将数据从Js发送到Flask时,我将其存储在 session 上,并且在特定的路由上可以正常工作:

I have a Javascript application and a Flask application. When the user send data from Js to Flask, I store it on session and it works fine at a specific route:

@app.route(...)
def user(...):
    session['name'] = name

    print(session['name']) # Works !

但是当我从另一个方法/路由获取会话中的值时,会话为空:

But when I tr to get the values on session from another method / route the session is empty:

@app.route(...)
def current():
    print(session.keys(), session.values) # Empty !

我已经安装了 Flask Session ,并将配置设置为:

I have installed Flask Session and set the config to:

'SECRET_KEY': b'...',

'SESSION_TYPE': 'filesystem', # Memcache, null and redis

'SESSION_PERMANENT': False, # True

然后启动Flask应用程序,它不起作用.在向会话添加一些新值后仍然无法正常工作,我还尝试设置 session.modified = True .

And then started the Flask application and it not work. I have also try to set session.modified = True after I add some new value to session and still not work.

我在Stack Over Flow,Reddit等上阅读了很多线程;没有任何效果.请提示?

I have read lots of threads on Stack Over Flow, Reddit, etc; and nothing worked. Tips please ?

推荐答案

TL; DR,在后端启用CORS和凭据支持,并在发出请求时在前端代码中使用凭据.

TL;DR, enable CORS and credentials support on the back end, and use credentials in the front end code when issuing requests.

我最近遇到了类似的问题,当时我在单独的应用程序中开发前端和后端.我注意到,每次我从前端客户端发出请求时,都会为每个请求创建一个新会话,这将使后端的会话存储迅速膨胀,并且即使不是没有可能,也使用户难以跟踪.

I recently ran into a similar issue where I was developing a front end and a back end in separate apps. I noticed that each time I issued a request from the front end client, it would create a new session for each request, which would rapidly bloat the session storage on the back end and made user tracking difficult if not impossible.

我假设您的Javascript应用程序和Flask应用程序是分开运行的(即javascript不在Flask应用程序提供的模板上,因此js请求来自不同的来源).

I'm assuming that you're Javascript app and Flask app are running separately (i.e., the javascript is not on a template being served by the Flask app and hence the js requests are coming from a different origin).

假设我们有一个简单的应用程序,它在端口5000上运行了Flask-Session:

Suppose we have a simple app with Flask-Session enabled running on port 5000:

from flask import Flask, session
from flask_session import Session

app = Flask(__name__)

SECRET_KEY = "changeme"
SESSION_TYPE = 'filesystem'
app.config.from_object(__name__)
Session(app)

@app.route('/foo')
def foo():
    return session.sid


@app.route('/bar')
def bar():
    return session.sid

现在,如果我们在浏览器上导航到任一路由,就可以运行应用程序(例如, http://localhost:5000/foo ),我们将获得相同的会话ID.如果打开另一个选项卡,打开开发人员工具并在控制台中发出以下命令,则会出现cors错误:

Now if we run the app if we navigate to either route on a browser(e.g., http://localhost:5000/foo), we would get the same session id. If you open another tab, open the developer tools and issue the following command in the console, you'd get a cors error:

// Using fetch, you can use jquery or axios    
fetch("http://localhost:5000/foo").then(response => {
    return response.text()
}).then(data => {
    console.log(data)
})

您可以通过安装Flask-CORS并将应用包装到CORS类中来轻松解决此问题:

You can fix this easily by installing Flask-CORS and wrapping your app in the CORS class:

from flask import Flask, session
from flask_session import Session
from flask_cors import CORS

app = Flask(__name__)

SECRET_KEY = "changeme"
SESSION_TYPE = 'filesystem'
app.config.from_object(__name__)
Session(app)
CORS(app)

@app.route('/foo')
def foo():
    return session.sid


@app.route('/bar')
def bar():
    return session.sid

现在,如果您运行上面的javascript fetch函数,则即使调用相同的路由,每次调用请求时,它也会打印出不同的会话ID.这是因为Flask无法跟踪会话,除非您从同一来源发出请求,或者除非您提供了一些方法来让Flask标识会话.您可以通过允许传递凭据来从JS中进行此操作:

Now if you run the javascript fetch function above, it prints out a different session id each time the request is invoked, even for the same route. That's because Flask can't track the session unless you're issuing the requests from the same origin or unless you provide some way for flask to identify the session. You can do this from your JS by allowing credentials to be passed:

fetch("http://localhost:5000/foo",
    { credentials: 'include' }).then(response => {
        return response.text()
}).then(data => {
    console.log(data)
})

但是,您将收到另一个有关Access-Control-Allow-Credentials的CORS错误.您可以通过导入cross_origin装饰器,将路线包装在装饰器中并传递supports_credentials = True到装饰器,在Flask应用中解决此问题.烧瓶代码如下所示:

However, you will get another CORS error regarding Access-Control-Allow-Credentials. You can fix this in you're Flask app by import the cross_origin decorator, wrapping your routes in the decorator and passing supports_credentials=True to the decorator. The flask code would look something like this:

from flask import Flask, session
from flask_session import Session
from flask_cors import CORS, cross_origin

app = Flask(__name__)

SECRET_KEY = "changeme"
SESSION_TYPE = 'filesystem'
app.config.from_object(__name__)
Session(app)
CORS(app)

@app.route('/foo')
@cross_origin(supports_credentials=True)
def foo():
    return session.sid


@app.route('/bar')
@cross_origin(supports_credentials=True)
def bar():
    return session.sid

现在flask可以跟踪请求者的会话(在本例中为运行Javascript应用程序的浏览器).

Now flask can track the session by the requester (in this case, the browser running the Javascript app).

这篇关于烧瓶会话不保留数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆