python - flask 为每个响应设置 Cookie

标签 python session cookies flask

我在我的应用中使用了 flask session。在我的一个处理程序中,我设置了 session 值,而在其他处理程序中没有设置 session 。但是我发现在每个响应中都有一个http header: Set Cookie exists。为什么会这样?

app = Flask(__name__)
app.secret_key = r"A0Zr98j/3yX R~XHH!jmN'LWX/,?RT"

@app.route('/auth/login', methods=['POST'])
@crossdomain(origin='*')
def authlogin():
    user = User(username=username, registered_at=sqlnow())
    user.accounts = [Account(provider='weibo', access_token=access_token, uid=uid)]
    account = user.accounts[0]

    session['user_id'] = account.user_id
    return jsonify({
        'status': 'success',
        'data': {
            'user_id': account.user_id,
            'uid': account.uid
        }
    })

@app.route('/api/movies/<movie_type>')
def moviescoming(movie_type):
    if movie_type == 'coming':
        return getmovies(MOVIE_TYPE_PLAYING, offset, limit)
    else:
        return getmovies(MOVIE_TYPE_COMING, offset, limit)

app.run(host='0.0.0.0', debug=True)

代码显示在这里: https://github.com/aisensiy/dianying/blob/master/index.py

最佳答案

简短回答:

这是设计使然,但最近 Flask 中的更改允许您通过使用 SESSION_REFRESH_EACH_REQUEST 选项更改此行为。截至发布此答案时,该选项尚未出现在 Flask 的稳定版本中。

长答案

让我们回过头来讨论一下 cookie 应该如何工作:

Cookie 作为标准

RFC 6265定义 a cookie should expire当代理(浏览器)声明 session 关闭时(通常是在浏览器关闭时),除非提供了某种机制来告诉浏览器 cookie 何时应该实际过期:

Unless the cookie's attributes indicate otherwise, the cookie [...] expires at the end of the current session (as defined by the user agent).

[...]

If a cookie has neither the Max-Age nor the Expires attribute, the user agent will retain the cookie until "the current session is over" (as defined by the user agent).

如果服务器希望 cookie 在代理重新启动后继续存在,则需要设置过期时间。请注意,Expires 属性通常是首选,因为 Internet Explorer 有一个 history of poor support for max-age。 .

创建永久性 Cookie

因此,不可能说 cookie 应该是“永久的”。当人们谈论“永久”cookie 时,他们真正谈论的是在浏览器重新启动后仍然存在的 cookie。我知道有两种创建此“永久”cookie 的策略:

  • 将 cookie 的过期时间设置为足以被视为永久的时间(例如 9999 年)。
  • 将 cookie 的过期时间设置为 future 相对较近的时间(例如 31 天),但每次使用 cookie 时都会再次更新过期时间。例如,在 1 月 1 日,我们将 cookie 设置为在 2 月 1 日过期,但是当用户在 1 月 2 日使用 cookie 时,我们正在更新 cookie(通过使用 Set-Cookie)以拥有它2 月 2 日到期。

第一种方法要求 Set-Cookie header 只设置给客户端一次(除非 cookie 内容需要更改)。

第二种方法需要在每次更新时发送 Set-Cookie header ,以便在用户继续使用该服务时不断“推迟”过期。请注意,它也不是真正的“永久”,因为超过 31 天未使用您网站的用户的 cookie 将过期。

RFC 6265 在 defining the expiration date 上确实有一些话要说:

Although servers can set the expiration date for cookies to the
distant future, most user agents do not actually retain cookies for
multiple decades. Rather than choosing gratuitously long expiration
periods, servers SHOULD promote user privacy by selecting reasonable
cookie expiration periods based on the purpose of the cookie. For
example, a typical session identifier might reasonably be set to
expire in two weeks.

因此,虽然它没有明确说明是否要不断更新到期日期,但它似乎确实在说使用遥远的 future 日期不应被视为一种好的做法。

Flask对“永久Cookies”的实现

Flask 在设计上使用了第二种方法(使用 Set-Cookie 不断更新 cookie 过期时间)。默认情况下,cookie 的有效期为 future 31 天(可由 PERMANENT_SESSION_LIFETIME 配置)。对于每个请求,Flask 将使用另一个 Set-Cookie 将过期时间再推迟 31 天(或您将永久 session 生命周期值设置为的任何值)。因此,您看到的每个请求上的 Set-Cookie 都是预期的,即使 session 没有更改也是如此。

然而,最近在 pull request regarding using Set-Cookie only when the cookie changes 中出现了讨论。 .这导致了 new feature允许用户更改其工作方式。 Flask 将继续按原样工作,但用户可以将新的 SESSION_REFRESH_EACH_REQUEST 选项设置为 False,这将导致 Set-Cookie header 仅在 cookie 时发送变化。

新项目记录为:

this flag controls how permanent sessions are refresh [sic]. If set to True (which is the default) then the cookie is refreshed each request which automatically bumps the lifetime. If set to False a set-cookie header is only sent if the session is modified. Non permanent sessions are not affected by this.

这个新选项与现有的 PERMANENT_SESSION_LIFETIME 一起,允许 Flask 开发人员更好地调整他们的“永久”cookie 将如何设置为过期。

截至此答案的发布日期(2013 年 12 月 24 日),SESSION_REFRESH_EACH_REQUEST 选项尚未成为任何 Flask 版本的一部分,因此希望使用它的用户需要等待 future 的 Flask发布。

关于python - flask 为每个响应设置 Cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20764566/

相关文章:

javascript - 为什么 Google Chrome 在崩溃后重新启动时不删除 session cookie?

javascript - 检查 cookie 是否存在的更快更短的方法

python - mpmath 中的逐元素运算

Python 多个 MySQL 插入

python - Pandas get_dummies 输出 dtype 整数/ bool 值而不是 float

PHP 不填写 session 文件

cookies - 在 CakePHP 3 中,按照教程,为什么登录表单会静默失败?

从 Python 运行 Spark 时 Java 堆大小错误

javascript - Internet Explorer 中的快速 session

c# - ASP.NET + C# HttpContext.Current.Session 为空(WebService 内部)