如何使用Pyramid检查浏览器cookie支持

时间:2012-02-15 09:54:59

标签: python cookies session-cookies pyramid

我想知道,何时是正确的时刻以及如何检查浏览器Cookie支持。

我知道我必须检查下一个请求,例如,烧杯,查找会话密钥_creation_timerequest.headers['Cookie'] ...如果找不到则引发异常,但我不知道想要为每个请求做那样或类似的事情。我的应用程序的某些部分不需要cookie,如主页或信息,常见问题页面......

当用户退出时,会话被删除或失效,我曾经重定向到主视图,如果我在那一刻检查session key,我找不到但是并不意味着有这个问题。

我在登录视图开头使用的一个例子:

 try: request.headers['Cookie']
 except KeyError:
   return HTTPFound(location=request.route_url('home'))

另请注意,如果我尝试使用request.session.flash(msg, 'error')打印错误消息或在主视图的开头再次使用代码段并使用控制返回变量使用模板呈现消息,则在注销后它将被错误地显示出来。

我正在寻找解决问题的最优雅的方式...也许订阅一个活动?...写下一个函数来调用一些感兴趣的视图?

1 个答案:

答案 0 :(得分:3)

有一些事情可能导致你的问题。

在我继续之前...... FYI Pyramid使用WebOb来处理请求和响应对象

情景1

如果您在金字塔下调用set_cookie,然后执行重定向,则不会发送set_cookie。这是因为重定向会创建一个新的响应对象。

有几种解决方法:

  1. 最简单的方法是在提升/返回重定向时将响应标头复制到cookie中

    return HTTPfound( "/path/to/redirect", headers=[ (k,v) for (k,v)\
    in self.request.response.headers.iteritems() if k == 'Set-Cookie']  )
    

    OR

    resp = HTTPFound(location='/path/to/redirect') 
    return self.request.response.merge_cookies(resp) 
    

    我还应该注意,MOST浏览器接受重定向的cookie,但Safari不接受。

  2. 另一种方法是使用金字塔的钩子在幕后转换cookie。我写了自动化的订阅者。他们在pypi和github。 https://github.com/jvanasco/pyramid_subscribers_cookiexfer

  3. 场景2

    在Pyramid中有两种处理会话的方法。 Pyramid有自己的会话库,然后有Beaker,它为Pylons处理sessions并且有很多人使用的Pyramid支持。我不能说pyramid.session,但是Beaker有两种模式来杀死会话:

    delete()
    Delete the cookie, and clear the session
    
    invalidate()
    Clear the contents and start a new session
    

    如果您致电invalidate(),则Beaker会话cookie保持不变并清除所有会话数据 - 因此您可以开始将新数据存储到空会话对象中。

    如果您致电delete(),Cookie会被会话数据杀死。如果您将新信息添加到会话IIRC中,它将进入新的sessionid / cookie。但是,正如我在上面第一部分中提到的,set_cookie将被调用,但在重定向期间被抛出。因此,如果您delete()会话,然后不迁移set_cookie标头...客户端将永远不会收到会话标识符。

    金字塔下的Cookie的一些示例行为

    重定向行为

    • 用户访问网站并获得Cookie:SessionId = 1
    • 用户点击登录
      • App将登录状态保存到会话“1”
      • App使用“LoggedIn = 1”
      • 调用set_cookie
      • 应用程序调用重定向到/ home
      • 重定向已发送,没有Cookie
    • 用户登陆/ home
      • 应用只会看到“SessionId = 1”
      • 的Cookie

    使用重定向删除行为:

    • 用户点击退出
      • 应用程序在会话中调用'delete()',终止数据存储区并在request.response中放置set_cookie以使旧cookie过期。如果创建了一个新的sessionid,那么也会发送它。
      • 如果应用呈现回复,则客户端会收到Cookie
      • 如果应用重定向,则客户端不会收到标头以使Cookie过期或设置新的

    带有重定向的无效行为:

    • 用户点击退出
      • 应用程序在会话中调用'invalidate()',从而终止数据存储
      • App设置自定义“loggedout = 0”Cookie
      • 如果应用呈现回复,则客户端会收到Cookie
      • 如果app重定向:
        • 客户端未收到“loggedout = 0”标题
        • 客户端仍然具有旧会话cookie,但它在后端被无效/清除,因此它们被有效锁定。

    旁注:我个人不喜欢使用处理所有标题的request.headers接口来获取cookie。我有更好的运气request.cookies - 它会返回一个cookie字典。