【问题标题】:CakePHP Session updates but cookie expiry doesn'tCakePHP 会话更新,但 cookie 没有过期
【发布时间】:2019-04-22 11:45:51
【问题描述】:

小问题:

为什么当我的会话过期时间在服务器上更新时,我的会话 cookie 的过期时间没有在浏览器中更新?

长问题:

几周前我发布了一个similar question,但我当时并没有所有的事实。我现在有了更多详细信息,并且问题的性质发生了变化,因此我将其作为一个新问题发布。

首先,在 CakePHP 2 中,我为会话设置了 APP/Config/core.php:

    Configure::write('Session', array(
        'defaults' => 'database',
        'cookie' => 'mycookie',
        'timeout' => 1 // 1 minute - just for testing
    ));

所以,我在我的应用程序中加载了一个页面,该页面在数据库中创建了会话。到目前为止一切顺利。

会话被标记为在1341288066 到期,等于Tue, 03 Jul 2012 04:01:06 GMT。同样,这很棒,因为那是从现在开始的 1 分钟。正是我想要的。

如果我查看 Firefox 的 cookie 屏幕,我会发现 cookie 与我预期的一样:

    Name: mycookie
    Content: aqm0gkmjfsuqje019at8cgsrv3
    Host: localhost
    Path: /
    Send for: Any type of connection
    Expires: Tue 03 Jul 2012 11:01:06 AM ICT  // (04:01:06 GMT)

现在,在这 1 分钟的窗口内,我返回我的应用并刷新页面。然后,我检查会话以查看它是否已更新。它显示1341288122 与会话ID aqm0gkmjfsuqje019at8cgsrv3 相等,这等于Tue, 03 Jul 2012 04:02:02 GMT,这又是我所期望的。会话的到期时间已更新为距离我上次重新加载页面的 1 分钟。

不幸的是,浏览器中的 cookie 仍然设置为 Expires: Tue 03 Jul 2012 11:01:06 AM ICT(即:04:01:06 GMT),这正是它所做的,这意味着下次我按下刷新时,Cake 会生成一个全新的会话 ID,即使旧的在技术上仍然有效。

我的问题基本上是这里发生了什么?为什么 cookie 没有在浏览器中更新为新的到期日期?

【问题讨论】:

  • 如果您在会话日期使用文件系统,文件夹是否可写? app/tmp 应该是可写的。
  • @DavidYell 会话更新正常。未更新的是客户端计算机上的 cookie 到期日期。
  • 我可以重现这个并且希望它像你一样以不同的方式工作。提交了一个错误,让我们看看我们是否都弄错了...cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/…
  • @pixelistik 好吧,Mark Story 已经为它设定了一个里程碑,所以我想我们并没有想象到 :-) 感谢您发布这个错误,我无法解释它显然我自己。你为什么不继续发布这个问题的答案来解释这是 CakePHP 的一个缺点,它将在 2.3.0 中解决,我会将其标记为正确答案并奖励我承诺的赏金。
  • @Joseph 好的,我试图把它总结在一个答案中。感谢您发现这一点!

标签: session cakephp cookies session-cookies


【解决方案1】:

您发现的问题确实是出乎意料的,并结束了他们应该保持活跃的会话。

这是 CakePHP 如何使用 PHP 的 Session 函数的结果。 CakePHP bugtracker 中有一个条目 (#3047),其中 Mark Story(CakePHP 开发人员)agrees 应该修复

我同意 cookie 应与存储在会话中的会话时间一起更新。然而,PHP 的会话处理内部功能并不是这样工作的。似乎有几种不同的方法可以解决此问题。

由于这将改变当前的行为(尽管它可能很奇怪),但修复被推迟到 2.3 版。

我认为在 PHP 之外管理 cookie 状态将是最合适的解决方案。不过,我不知道这对于现有应用程序的更改有多安全。改变会话的工作方式可能会带来巨大的变化,并且允许用户长时间保持登录状态可能并不是所有开发人员所期望的。

【讨论】:

  • 感谢您确认我没有疯 :-) 我刚刚将您的答案标记为正确并授予赏金。
  • 我一直想知道问题出在哪里。在此之前,您可以使用 AutoLogin 组件让您的用户不会注意到连续注销:dereuromark.de/2012/02/02/more-persistent-sessions-in-cake2-x
  • 2.3 或更高版本是否解决了这个问题?我已阅读发行说明,但找不到任何明显的内容。
【解决方案2】:

这似乎是 PHP 处理会话的方式。 PHP 不会在每个请求上更新 cookie(请参阅:http://php.net/manual/en/function.session-set-cookie-params.php#100672)。 CakePHP 不依赖此 cookie 中的到期时间,而是将当前时间与 Session::_validAgentAndTime() 中的实际会话超时时间进行比较。

【讨论】:

  • 我不希望 PHP 更新每个请求的 cookie,但如果我在 CakePHP 中专门为会话设置了一个新的到期时间,并且该到期时间过去到期cookie 的时间,CakePHP 不应该努力修改 cookie 的过期时间吗?如果不能,那么为什么可以将会话的生命周期延长到最初设置的 cookie 的生命周期之外呢?如果 cookie 已过期且无法扩展,则扩展会话是无用的。
  • 也许应该,也许不应该。这只是两种不同的行为。 1(当前行为):用户在站点周围移动 比 cookie 更长,当他们关闭浏览器时会话结束,因为 cookie 已过期; 2(通过更新 cookie 可能的其他行为):用户在站点周围移动,会话在上次访问后 X 秒结束。如果您希望 cookie 在每个请求上扩展,您可以编写自定义会话处理程序。
  • 但是如果在场景 1 中 cookie 已经过期,CakePHP 怎么知道会话 ID?这就是它归结为,IMO。
  • 何时清除 cookie 取决于浏览器。 Chrome 会在它们过期时清除它们,但 Firefox 似乎会保留它(我找不到一致性)。这意味着,在 Fx 中,PHP 会话将保持有效,因为 cookie 仍然存在。我不知道 PHP 是否在内部手动使 cookie 无效,但从会话存在超过 cookie 的过期时间这一事实来看,我认为它不会。我想在 Chrome 中,您会在 cookie 过期后立即注销。不一致:/
  • @pixelistik 这正是问题所在,即使会话仍然有效,一旦 cookie 过期,CakePHP 就会“忘记”会话 ID。这就是我问题的重点。
【解决方案3】:

结合使用这两个参数可以解决问题。

Configure::write('Session', array(
    'cookie' => 'CAKEPHP',
    'defaults' => 'php',
    'timeout' => 60,                // 60 minutes: Actual Session Timeout
    'cookieTimeout' => 1440,        // 1440 minutes: 24 hrs: Actual Cookie Timeout
    'autoRegenerate' => true,
    'requestCountdown' => 1,
    'checkAgent' => false,
));
  • autoRegenerate:刷新后生成Session Cookie。重新生成会话 Cookie 的刷新次数由下一个参数确定。
  • requestCountdown:使该参数的值尽可能低。这是刷新/重新加载的次数,之后会话 Cookie 将重新生成。

【讨论】:

    猜你喜欢
    • 2011-04-10
    • 1970-01-01
    • 2019-05-27
    • 2011-04-16
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    相关资源
    最近更新 更多