flask:通过AJAX获取会话时间

时间:2016-08-31 19:00:09

标签: python ajax session flask

我正在使用Flask,其中存储在Redis后端的服务器端会话的flask-session插件。我将flask设置为使用持久会话,会话超时。如何在不重置超时的情况下发出AJAX请求以获得会话剩余时间?

这个想法是客户端在显示超时警告(或注销用户)之前检查服务器,以防用户在同一浏览器的不同选项卡/窗口中处于活动状态。

编辑:经过一番挖掘,我找到了配置指令SESSION_REFRESH_EACH_REQUEST,它出现我应该可以用来完成我想要的:将其设置为False,然后只有在会话中实际发生了变化时才会刷新会话,所以我应该能够在没有会话超时变化的情况下发出超时请求。它是在0.11中添加的,我运行的是0.11.1,所以它应该可用。

不幸的是,在实践中,这似乎不起作用 - 至少在检查redis密钥的ttl以获得剩余时间时。我查了一下,session.modified是假的,所以不仅仅是我在修改会话的请求中做了一些事情(除非它没有设置该标志)

1 个答案:

答案 0 :(得分:0)

以下作品虽然相当骇人听闻:

在应用__init__.py或您致电Session(app)init_app(app)的任何地方:

#set up the session
Session(app)

# Save a reference to the original save_session function so we can call it
original_save_session = app.session_interface.save_session

#----------------------------------------------------------------------
def discretionary_save_session(self, *args, **kwargs):
    """A wrapper for the save_session function of the app session interface to
    allow the option of not saving the session when calling specific functions,
    for example if the client needs to get information about the session
    (say, expiration time) without changing the session."""

    # bypass: list of functions on which we do NOT want to update the session when called
    # This could be put in the config or the like
    #
    # Improvement idea: "mark" functions on which we want to bypass saving in
    # some way, then check for that mark here, rather than having a hard-coded list.
    bypass = ['check_timeout']

    #convert function names to URL's
    bypass = [flask.url_for(x) for x in bypass]

    if not flask.request.path in bypass:
        # if the current request path isn't in our bypass list, go ahead and
        # save the session normally
        return original_save_session(self, *args, **kwargs)

# Override the save_session function to ours
app.session_interface.save_session = discretionary_save_session

然后,在check_timeout函数(位于上面的旁路列表中)中,我们可以执行以下操作以获得会话的剩余时间:

@app.route('/auth/check_timeout')
def check_timeout():
    """"""
    session_id = flask.session.sid

    # Or however you want to get a redis instance
    redis = app.config.get('REDIS_MASTER')

    # If used
    session_prefix = app.config.get('SESSION_KEY_PREFIX')

    #combine prefix and session id to get the session key stored in redis
    redis_key = "{}{}".format(session_prefix, session_id)

    # The redis ttl is the time remaining before the session expires
    time_remain = redis.ttl(redis_key)

    return str(time_remain)

我确信上面的内容可以改进,但结果是符合要求的:当调用/auth/check_timeout时,会返回会话剩余的时间,而不会以任何方式修改会话。