多个实例随机注销用户

时间:2013-05-09 19:58:10

标签: php session yii appfog

我在Appfog上运行Yii-app。每当我尝试拥有多个实例时,就不再可能保持登录状态。

我知道多个实例需要会话的共享存储,我已经使用EDMSHttpSession实现了它。它确实可以在localhost上运行,也就是说我可以登录,重启Apache并保持登录状态。另外,如果我删除了数据库中的会话记录,我就退出了。这使我得出结论,PHP正在使用数据库来存储会话。

我无法理解为什么我的会话共享存储无法在Appfog上运行,我想了解如何调试它。

更多背景信息:

  • 我使用cookies进行自动登录。它们应该有效期为30天(和 他们是根据Chrome检查员),但从来没有更多的工作 然后几个小时(浏览器会话,我猜) - 不是在localhost,而不是在 Appfog。
  • 启用多个实例和自动登录(即我点击“记住我”)我仍然会被随机踢出,通常是在2或3之后 页面刷新。据我所知,饼干应该签到你 什么不管服务器会话?
  • 在Appfog上我有一个SSL端点,在localhost上我没有。
  • 我已经检查过Appfog上的共享会话存储是否正在获取新会话(查看数据库表)

更新

我做了一些测试,也许我的结果会对某人产生影响。

我清除所有Cookie并重启我的Appfog应用。我登录,然后检查     “记住账号”。现在,以下响应Set-cookie标头是:

Set-Cookie:PHPSESSID=vrfoi0o15v3qps2644uqtvkfa1; path=/  
Set-Cookie:PHPSESSID=db38s1k1vp5ngll837ac0vh0u7; path=/  
Set-Cookie:73dfaf673b71b1f92d34b8ab63dab17b=812bbcfd4f5b3be91f8c85d39c3b37bb93e4c6b8a%3A4%3A%7Bi%3A0%3Bs%3A24%3A%225087ea0b3145a75545000000%22%3Bi%3A1%3Bs%3A22%3A%22demo%40playbackenergy.se%22%3Bi%3A2%3Bi%3A2592000%3Bi%3A3%3Ba%3A0%3A%7B%7D%7D; expires=Sun, 09-Jun-2013 08:32:24 GMT; path=/

在后续请求中,请求Cookie标头为:

Cookie:PHPSESSID=db38s1k1vp5ngll837ac0vh0u7; 73dfaf673b71b1f92d34b8ab63dab17b=812bbcfd4f5b3be91f8c85d39c3b37bb93e4c6b8a%3A4%3A%7Bi%3A0%3Bs%3A24%3A%225087ea0b3145a75545000000%22%3Bi%3A1%3Bs%3A22%3A%22demo%40playbackenergy.se%22%3Bi%3A2%3Bi%3A2592000%3Bi%3A3%3Ba%3A0%3A%7B%7D%7D

我使用"db38s1k1vp5ngll837ac0vh0u7"在数据库中查找我的会话。该行看起来像这样(请注意,在数据库中找不到vrfoi0o15v3qps2644uqtvkfa1):

{
  "_id" : ObjectId("518cb0981045979e06000000"),
  "data" : "73dfaf673b71b1f92d34b8ab63dab17b__id|s:24:\"5087ea0b3145a75545000000\";73dfaf673b71b1f92d34b8ab63dab17b__name|s:22:\"demo@playbackenergy.se\";73dfaf673b71b1f92d34b8ab63dab17b__states|a:0:{}73dfaf673b71b1f92d34b8ab63dab17brole|s:4:\"demo\";",
  "expire" : 1368176186,
  "id" : "db38s1k1vp5ngll837ac0vh0u7"
}

现在我再次重新启动我的Appfog应用程序并尝试导航到我的应用程序中的另一个页面。现在我退出了。

重定向到登录页面之前的请求Cookie标头(与之前相同):

Cookie:PHPSESSID=db38s1k1vp5ngll837ac0vh0u7; 73dfaf673b71b1f92d34b8ab63dab17b=812bbcfd4f5b3be91f8c85d39c3b37bb93e4c6b8a%3A4%3A%7Bi%3A0%3Bs%3A24%3A%225087ea0b3145a75545000000%22%3Bi%3A1%3Bs%3A22%3A%22demo%40playbackenergy.se%22%3Bi%3A2%3Bi%3A2592000%3Bi%3A3%3Ba%3A0%3A%7B%7D%7D

2 个答案:

答案 0 :(得分:1)

你只询问了如何调试的建议,所以你去了:

  • 为每个实例布局文件添加不同的隐藏字符串,以便您可以查看为当前请求提供的实例
  • 检查浏览器中请求/响应标头中的Cookie,查看是否每次请求都发送了相同的会话ID,以及从服务器发回新的会话ID

这可以帮助您找出会话丢失的条件。

<强>更新

  • 查看会话是否真的被破坏,或者Yii是否只是将您注销。要执行此操作,请以guest用户身份向会话写入内容,然后尝试在重新加载时丢失此信息。
  • 禁用allowAutoLogin并查看它是否现在有效。

答案 1 :(得分:0)

最后,我已经成功调试了这个问题,感谢MichaelHärtl的建议。

我必须解决两件事

1)在protected / config / main.php

中指定application-id
array(
    'name' => 'My App',
    'id' => 'yourdomain',
    ...,
)

如果不这样做,多个实例将具有不同的ID。由于Yii使用app-id的哈希来为会话变量添加前缀,因此它可以在不同的实例之间共享 - 尽管您有共享会话存储。这篇Yii文章更深入地解释了它:http://www.yiiframework.com/wiki/135/single-sign-on-across-multiple-subdomains/

2)使用CDN作为资产以及共享的chaching。显然资产文件夹(例如3f4ad45)可能在此实例之间有所不同,因此您必须使用共享存储。我使用扩展程序http://www.yiiframework.com/extension/s3assetmanager/来管理资产,使用https://github.com/aarondfrancis/yii-CMemCacheSASL作为缓存(MemCachier)。