TL;DR,在后端启用 CORS 和凭据支持,并在发出请求时在前端代码中使用凭据。
我最近遇到了一个类似的问题,我在不同的应用程序中开发前端和后端。我注意到,每次我从前端客户端发出请求时,它都会为每个请求创建一个新会话,这会迅速膨胀后端的会话存储,并且即使不是不可能,也很难进行用户跟踪。
我假设您是 Javascript 应用程序和 Flask 应用程序分别运行(即,javascript 不在 Flask 应用程序提供的模板上,因此 js 请求来自不同的来源)。
假设我们有一个启用了 Flask-Session 的简单应用在端口 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 错误:
// 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 装饰器,将您的路线包装在装饰器中并将supports_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 应用程序的浏览器)跟踪会话。