flask为每个响应设置Cookie

时间:2013-12-24 17:20:00

标签: python session cookies flask

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

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

1 个答案:

答案 0 :(得分:15)

简答:

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

长答案

让我们回顾并讨论如何开始使用Cookie:

Cookies作为标准

当代理(浏览器)声明会话关闭时(通常是关闭浏览器时),

RFC 6265定义a cookie should expire,除非提供了一些机制来告诉浏览器何时应该关闭cookie实际到期:

  

除非cookie的属性另有说明,否则cookie [...]   在当前会话结束时到期(由用户定义)   剂)。

     

[...]

     

如果cookie既没有Max-Age也没有Expires属性,那么   用户代理将保留cookie,直到“当前会话结束”   (由用户代理定义)。

如果服务器希望cookie能够在代理重新启动后继续存在,则需要设置过期时间。请注意,由于Internet Explorer具有history of poor support for max-age

,因此通常首选Expires属性

创建永久性Cookie

所以,不可能说cookie应该是“永久性的”。当人们谈论一个“永久性”cookie时,他们真正在谈论的是一个在浏览器重启后幸存下来的cookie。我知道有两种策略用于创建这个“永久”cookie:

  • 将Cookie的到期时间设置为足以被视为永久性的内容(例如9999年)。
  • 将Cookie的到期时间设置为将来相对较新的内容(例如,31天),但每次使用Cookie时,请再次更新到期日期。例如,1月1日我们将cookie设置为2月1日到期,但是当用户在1月2日使用cookie时,我们将更新cookie(使用Set-Cookie)以使其在2月2日到期。

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

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

RFC 6265在defining the expiration date上有点说法:

  

虽然服务器可以将cookie的到期日期设置为   遥远的未来,大多数用户代理实际上并没有为其保留cookie   几十年。而不是无偿选择长期到期   期间,服务器应该通过选择合理的方式来提升用户隐私   基于cookie目的的cookie有效期。对于
  例如,典型的会话标识符可以合理地设置为
  两周后到期。

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

Flask实施“永久性Cookies”

Flask使用第二种方法(通过Set-Cookie不断更新cookie过期)。默认情况下,Cookie的到期时间为31天(可由PERMANENT_SESSION_LIFETIME配置)。对于每个请求,Flask将使用另一个Set-Cookie将过期时间推迟另外31天(或者您设置永久会话生命周期值的任何内容)。因此,即使会话未发生更改,您看到的每个请求都会Set-Cookie

但是,最近在pull request regarding using Set-Cookie only when the cookie changes进行了讨论。这导致new feature允许用户更改其工作方式。 Flask将继续按原样运行,但用户可以将新的SESSION_REFRESH_EACH_REQUEST选项设置为False,这将导致仅在Cookie更改时发送Set-Cookie标头。

新项目记录为:

  

此标志控制永久会话的刷新方式[原文如此]。如果设置为   True(这是默认值)然后每个刷新cookie   请求会自动阻止生命周期。如果设置为False a   只有在修改会话时才会发送set-cookie标头。非   永久会议不受此影响。

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

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