Flask Session()对象不是永久的

时间:2018-09-21 01:49:46

标签: cookies flask session-cookies

在我的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会话的用法?

1 个答案:

答案 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中。