在我的Flask API中,我试图使会话保持永久性,以便即使在浏览器关闭后它也仍然存在。我的前端是用React编写的,并使用Fetch API发出请求。但是,在测试完我到目前为止的功能后,它似乎无法正常工作。我的代码(省略了一些无关的数据库工作):
@bp.route('/login', methods=('POST',))
def login():
...
error=None
res = {}
db = get_db()
cursor = db.cursor(dictionary=True)
...
user = cursor.fetchone()
...
if error is None:
session.clear()
session.permanent = True
session['userID'] = user['id']
current_app.logger.debug(session['userID'])
res['actionSuccess']= True
else:
res['actionSuccess'] = False
res['error'] = error
return jsonify(res)
到目前为止,我可以确定会话确实存储了userID值。然后,我写另一条路由来告诉我是否在会话中存储了一个userID值,如下所示:
@bp.route('/init', methods=('GET',))
def init():
userID = session.get('userID')
if userID is None:
res = {"signedIn": False}
else:
res = {"signedIn": True, "username": userID}
return jsonify(res)
但是,每次我调用'/ init'时,即使我以前登录也返回False。我不知道为什么会话在这里不是永久的。是因为我在计算机上本地运行客户端吗?我是否需要在Chrome浏览器的某处允许cookie?我使用Chrome浏览了为客户端存储的cookie,但没有“会话”存储在其中。我是否需要在前端额外存储一些cookie /会话,或者它们会自动存储?我是否误解了Flask会话的用法?
答案 0 :(得分:0)
经过大量研究后,发现会话为何无法正常运行! Flask会话本质上是cookie,我正在使用Fetch API来执行CORS操作。默认情况下,Fetch()不允许接收或发送Cookie,必须进行配置才能使用Flask会话。
在React.js客户端上,我通过为'凭据'设置'include'来做到这一点:
fetch(url, {
method: 'POST',
mode: 'cors',
body: JSON.stringify(loginObj),
credentials: 'include',
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
...
由于采用了这种配置,因此该请求不被视为“简单请求”,并且客户端实际上将使用OPTIONS请求“预检” POST请求。这意味着在发送我的POST请求之前,将首先向我的Flask服务器发送一个OPTIONS请求测试,以检查服务器是否具有正确的访问权限。
飞行前OPTIONS请求将进行测试,以查看服务器的响应是否具有正确的标头,其中包含“ Access-Control-Allow-Origin”,“ Access-Control-Allow-Credentials”和“ Access-Control-Allow-标头。如果由OPTIONS请求发送的测试失败,则不会发送实际的POST请求,并且会出现Fetch错误。
然后我在Flask服务器上相应地设置标头,如下所示:
@bp.route('/login', methods=('POST','OPTIONS'))
def login():
if request.method == 'OPTIONS':
resp = Response()
resp.headers['Access-Control-Allow-Origin'] = clientUrl
resp.headers['Access-Control-Allow-Credentials'] = 'true'
resp.headers['Access-Control-Allow-Headers'] = "Content-Type"
return resp
else:
'''
use session for something
'''
res['actionSuccess'] = False
js = json.dumps(res)
resp = Response(js, status=200, mimetype='application/json')
resp.headers['Access-Control-Allow-Origin'] = clientUrl
resp.headers['Access-Control-Allow-Credentials'] = 'true'
resp.headers['Access-Control-Allow-Headers'] = "Content-Type"
return resp
请注意,由于客户端无法识别Python布尔值,因此将“ Access-Control-Allow-Credentials”设置为“ true”,而不是Python布尔值True。
因此,应将Flask Session对象存储在您的cookie中。