【问题标题】:Flask Session() object not permanentFlask Session() 对象不是永久的
【发布时间】:2019-02-25 09:06:20
【问题描述】:

在我的 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)

到目前为止,我可以看出会话确实在存储用户 ID 值。然后我写了另一个路由来告诉我一个 userID 值是否存储在 session 中,如下所示:

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

【问题讨论】:

    标签: cookies flask session-cookies


    【解决方案1】:

    经过大量研究,找出会话不起作用的原因! Flask 会话本质上是 cookie,我使用 Fetch API 来执行 CORS 操作。 Fetch() 默认情况下不允许接收或发送 cookie,必须进行配置才能使用 Flask 会话。

    在我的 React.js 客户端上,我通过为 'credentials' 设置 '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
    

    请注意,“Access-Control-Allow-Credentials”设置为“true”,而不是 Python 布尔值 True,因为客户端无法识别 Python 布尔值。

    因此,Flask Session 对象应该存储在您的 cookie 中。

    【讨论】:

    • credentials: 'include' 这对我有用!我可以在开发者模式下看到 cookie
    猜你喜欢
    • 2012-08-26
    • 2013-02-28
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    相关资源
    最近更新 更多