【问题标题】:Session being lost after multiple (cancelled) POST requests多次(取消)POST 请求后会话丢失
【发布时间】:2014-11-06 13:03:11
【问题描述】:

我们使用带有 Memcached 的外部 Ubuntu 服务器作为会话存储。自从我们从数据库会话切换后,我们收到了来自正在注销的用户的随机投诉。

问题:

  1. 用户在会话到期之前被注销。在某些情况下,他们在登录后一两分钟就会被注销。
  2. 我们的网络服务器日志或 Memcached 日志中没有出现任何错误。
  3. 他们的会话 ID 在注销后保持不变。

今天,我们的一位用户偶然发现了一种重现该行为的方法。在允许他们设置自定义日期范围的页面上,他们反复按下“前一天”按钮,每次点击都会发送一个 POST 请求。例如,如果您单击该按钮 20 次,它将发送 20 个 POST 请求,其中 19 个将在最后一个成功完成之前被取消。一旦最终请求完成,似乎所有会话变量都丢失了。

我的 php.ini (CGI) 设置:

session.save_handler = memcache
session.save_path = "tcp://OURSERVERIP:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

注意:POST 请求正在加载同一域中的 iframe。

更新:似乎也遇到了用户以彼此身份登录的问题。会话 ID 冲突?

【问题讨论】:

  • @derp 不幸的是,日志并没有提供太多帮助,这让这变得如此令人沮丧。我将在几秒钟内为 Memcached 添加我的 php.ini 设置。
  • 也许你已经有了,但我还是想提一下在开始之前给session_name('myproject')
  • 你在使用session_regenerate_id()吗?
  • @JasperN.Brouwer 我直到前天才起床。还引入了基于用户代理的会话令牌,只是为了避免冲突。
  • 我们在使用 floatbox 2.45 时遇到了类似的问题,服务器中缺少一对图像。我们看到其中 4 个是 404。只有在 IE11 和 Edge 中,我们才能复制间歇性发生的问题。一旦我们添加了图像问题就消失了;)

标签: php session memcached


【解决方案1】:

我已经对您发布的所有内容进行了一些研究,以下是一些固定点:

会话 ID 冲突

根据This article,有 37^31 个不同的会话 ID。根据birthday paradox,您需要 2E24 个会话才能有 50% 的机会发生一对碰撞。你可以看到机会极低,但有可能。例如,如果您将会话 ID 存储在数据库中,然后稍后将其交给用户,这样他们就可以使用相同的会话 ID 一年甚至更长的时间,这样的机会就会增加一些。

多个同时会话请求

此时我不确定“前一天”按钮是否发送 ajax 请求,以便用户可以连续多次单击它而无需等待结果,或者他需要等待(至少部分)页面加载才能单击在新加载的页面中再次单击该按钮。在第一种情况下,数据包可能会在 Internet 中被打乱,并且最后发送的请求会比其他请求更早到达。现在当两个请求同时到达时会发生什么? 根据this SO question,会话数据被锁定,直到(通常)脚本完成执行。这会导致多个请求堆积在一个队列中,因此它应该是安全的,不会导致会话丢失。

脚本特定时间的弱点

这是最后一个要点,根据您的信息,我相信这是您会话丢失的原因。这取决于您的服务器是如何实现的,但是如果第 10 个“前一天”请求在 5 号之前到达会发生什么?第二个可能的原因是中断页面加载。 ajax 加载不会发生这种情况,但常规形式会发生这种情况。如果您在页面加载(并且可能仍在执行)之前单击前一天,您的 Web 浏览器会中断加载并请求新页面。 php 脚本执行应为aborted现在我根据session_write_close 在脚本终止时调用该函数,所以在这种情况下它仍然是会话安全的。 那么问题出在哪里?可能会再次出现在剧本中。想象一下,您的 php 脚本将在中间停止执行并立即保存会话。会发生什么?这取决于。取决于您如何处理会话,您在其中存储什么,何时存储它。它基本上可能在添加(回显)输出的任何行处死掉,因为那是它发现客户端浏览器不再监听连接的时候。

我相信这是原因,我可能是错的,因为只有你才能看到你的代码。我建议您查看代码并检查如果您的脚本提前终止或接收到无序的请求会发生什么。

编辑 我忘了考虑内存缓存。不幸的是我对此一无所知,所以一些不正确的东西被标记但没有从这个答案中删除,那是因为休息仍然可能是正确的原因。

【讨论】:

    【解决方案2】:

    从你写的我可以区分两个不同的问题:

    1. 用户被注销,但他们的会话 ID 没有改变。
    2. 用户的会话 ID 发生变化。

    这些可能是不同的问题,也可能是相同的问题,我不知道。更严重的问题是人们可以获得其他人的会话 ID。这很奇怪。

    如果我正确解释了您的问题,您的问题是:“其他人在使用 Memcached 的 Ubuntu 服务器上的会话是否有类似问题?”

    对不起,不,我没有那种经验。无法回答与您的源代码相关的问题,即使它们可能是您的问题的根源。尤其是ID的变化问题。

    你见过吗?

    http://php.net/manual/en/memcached.sessions.php#115306

    这听起来不像你的问题,但任何一点信息都可以提供帮助。

    至于我的建议:

    a:如果您想处理大量流量,您的服务器需要相当多的内存。检查您的服务器随着时间的推移有多少可用内存,它是否接近于零?这将导致旧会话从 MemCache 中清除并重置连接。

    b:检查所有404 Not Found 错误。使用浏览器控制台检查每个页面加载。图像或 CSS 文件上的 404 可能会重置会话,从而导致零星的会话丢失。

    c:确保您的会话 ID 没有重新生成。它可能会导致您描述的问题。 (https://bugs.php.net/bug.php?id=61470&edit=1)

    d:尝试在您的问题中添加更多源代码。给人们一些可以看和尝试的东西。如果长时间使用 http://ideone.com 之类的东西,我知道这不包括您的数据库或流量负载,但它可能会帮助我们找到您的问题。

    如果您确实解决了您的问题,请告诉我们。

    【讨论】:

      猜你喜欢
      • 2015-08-20
      • 2012-12-22
      • 2011-07-12
      • 1970-01-01
      • 2014-05-13
      • 2017-01-13
      • 2018-01-04
      • 2021-05-02
      • 1970-01-01
      相关资源
      最近更新 更多