【问题标题】:Django session cookie lost because of multiple concurrent requests由于多个并发请求,Django 会话 cookie 丢失
【发布时间】:2011-06-14 13:39:18
【问题描述】:

我正在构建一个应用程序,在该应用程序中,客户端不时地对服务器执行 ping 操作(我们先不讨论原因)。当服务器处理这些请求时,它会使用 request.user.is_authenticated() 检查客户端是否登录

看起来像这样:

def handle_ping_request(request):
    if request.user.is_authenticated():
       # Do something...
    else:
       # Do Something else...

我注意到,有时服务器会立即收到一个登录请求,然后是一个 ping 请求(来自同一用户)。然后客户端成功登录,响应返回一个新的会话 ID(登录用户的),并且(我猜)旧的会话 ID(匿名用户的)被删除。当 ping 请求被处理时,它的请求包含旧的 session-ID。因此,ping 请求返回第三个会话 ID,并且在客户端发出下一个请求时,客户端不再登录。

我的登录代码如下所示:

if not request.user.is_authenticated():
    user = auth.authenticate(...credentials...)

    if user and user.is_active:
        auth.login(request, user)

您对如何避免这个问题有什么建议吗?最好不涉及客户。

谢谢。

【问题讨论】:

    标签: python django session cookies


    【解决方案1】:

    在服务器上处理这个问题可能太麻烦了,因为您必须创建某种信号量系统,该系统还会尝试猜测当前是否有任何 ping 来自同样经过身份验证的客户端。我的建议是简单地将客户端代码更改为在等待对其登录请求的响应时不要 ping。

    【讨论】:

    • 如果客户端在登录之前 ping,则登录请求可能会在 ping 请求之前到达服务器。这意味着客户端在发送登录请求之前还必须等待所有 ping 请求完成。这似乎也是一种信号量机制:)
    • 确实如此,但至少客户端只有一个可精确识别的服务器,而服务器必须在所有当前会话的整体大海捞针中找到客户端的几个“针”会话,这看起来像更大的任务。
    【解决方案2】:

    您可以创建一个替代标准 contrib.auth.login method 的替代方案,它保留相同的会话 ID,而不是生成新的,方法是使用不生成新密钥的自定义身份验证后端,或创建自定义会话覆盖cycle_key() method in contrib.sessions.base 以重用相同密钥的后端。

    但是:想想你可能通过重用相同的会话密钥来打开自己的大门 - 根据使用该系统的位置,你会让自己对会话劫持更​​加开放(即:只有一个会话 id嗅探),以及缓存可能返回 unauth 页面内容而不是 auth 页面内容的潜在问题,因为 sessionid 在技术上是相同的,并且缓存无法区分这两种情况,等等等等。

    简而言之:默认情况下,它的工作方式是有原因的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-04
      • 2015-02-23
      • 1970-01-01
      • 2014-11-06
      • 2013-06-20
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多