首页 文章

多个(取消)POST请求后会话丢失

提问于
浏览
3

我们正在使用带有Memcached的外部Ubuntu服务器来进行会话存储 . 由于我们从数据库会话中进行了更改,因此我们已经有来自注销用户的随机投诉 .

问题:

  • 用户在会话到期之前正在注销 . 在某些情况下,他们在登录后一两分钟就会被注销 .

  • 我们的Web服务器日志或Memcached日志中没有出现错误 .

  • 他们的会话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冲突?

2 回答

  • 2

    我已经对你发布的所有内容做了一些研究,这里有一些固定点:

    会话ID冲突

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

    多个同时会话请求

    此时我不确定"previous day"按钮是否发送ajax请求,以便用户可以连续多次单击它而无需等待结果,或者他需要等待(至少部分)页面加载以在新加载时再次单击该按钮页 . 在第一种情况下,可能发生数据包可能在互联网中被加扰并且已经作为最后发送的请求将比其他请求更快地到达 . 现在当两个请求一次到达时会发生什么?根据这个SO问题,会话数据被锁定,直到(通常)脚本完成执行 . 这会导致多个请求堆积在队列中,因此它应该是安全的,并且不会导致会话丢失 .

    脚本特定于时间的弱点

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

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

    EDIT 我忘了考虑memcache了 . 不幸的是我对它一无所知所以标记了一些不正确的东西,但没有从这个答案中删除,这是因为休息仍然是正确的原因 .

  • 2

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

    • 用户已注销,但其会话ID不会更改 .

    • 用户的会话ID更改 .

    这些可能是不同的问题,或者相同,我无法分辨 . 更严重的问题是人们可以获得其他人的会话ID . 这很奇怪 .

    如果我正确地解释你的问题,你会问:"Do other people have similar problems with sessions on an Ubuntu server with Memcached?" .

    对不起,不,我没有那种经历 . 与您的源代码相关的问题无法回答,尽管它们可能是您问题的根源 . 特别是ID问题的变化 .

    你见过这个吗?

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

    它听起来不像你的问题,但任何信息都可以提供帮助 .

    As for my tips:

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

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

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

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

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

相关问题