为了账号安全,请及时绑定邮箱和手机立即绑定

Flask 会话不保留数据

Flask 会话不保留数据

HUX布斯 2021-07-05 09:14:17
我有一个 Javascript 应用程序和一个 Flask 应用程序。当用户将数据从 Js 发送到 Flask 时,我将其存储在其中session并且它在特定路线上工作正常:@app.route(...)def user(...):    session['name'] = name    print(session['name']) # Works !但是当我从另一个方法/路由获取会话值时,会话为空:@app.route(...)def current():    print(session.keys(), session.values) # Empty !我已经安装了Flask Session并将配置设置为:'SECRET_KEY': b'...','SESSION_TYPE': 'filesystem', # Memcache, null and redis'SESSION_PERMANENT': False, # True然后启动了 Flask 应用程序,它不起作用。我也尝试session.modified = True在向会话添加一些新值后进行设置,但仍然无法正常工作。我在 Stack Over Flow、Reddit 等上阅读了很多主题;没有任何效果。请提示?
查看完整描述

2 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

在后端启用 CORS 和凭证支持,并在发出请求时在前端代码中使用凭证。


我最近遇到了一个类似的问题,我在不同的应用程序中开发前端和后端。我注意到,每次我从前端客户端发出请求时,它都会为每个请求创建一个新会话,这会迅速膨胀后端的会话存储,并使用户跟踪变得困难(如果不是不可能的话)。


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


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


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 错误:


// 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 类中来轻松解决此问题:


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 执行此操作:


fetch("http://localhost:5000/foo",

    { credentials: 'include' }).then(response => {

        return response.text()

}).then(data => {

    console.log(data)

})

但是,您将收到另一个关于 Access-Control-Allow-Credentials 的 CORS 错误。您可以通过导入 cross_origin 装饰器,将您的路由包装在装饰器中并将 support_credentials=True 传递给装饰器,在您的 Flask 应用程序中解决此问题。烧瓶代码看起来像这样:


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 应用程序的浏览器)。


查看完整回答
反对 回复 2021-07-13
?
手掌心

TA贡献1942条经验 获得超3个赞

我在 html 中使用经典的 post 请求时遇到了同样的问题。会话仍然在之前的路由中存储值,在我发布请求后会清空自己。

我使用以下方法解决了这个问题:

app.config.update(SESSION_COOKIE_SAMESITE="None", SESSION_COOKIE_SECURE=True)

我分享这个以防其他人面临同样的问题。


查看完整回答
反对 回复 2021-07-13
  • 2 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号