sha*_*yyx 9 php authentication session memcached zend-framework2
在我们的Intranet应用程序中,我们使用SSO(单点登录)登录,而客户端和auth源应用程序上的会话都存储在memcached中.
会话设置为在垃圾收集器可能将其视为删除之前的12小时.两个应用程序都是使用ZF2编写的.
不幸的是,问题是,在一段时间后(我没有确切的值),浏览器会丢失导致重定向到auth origin的会话,其中会话仍处于活动状态,因此用户被重定向回客户端并且浏览器会话刷新.如果用户没有未保存的工作,这不是什么大问题,因为这两个重定向在1秒内发生,用户甚至可能没有注意到它们.
但是当用户有未保存的工作时,它确实是一个大问题,即使尝试保存它也会导致重定向,工作也就消失了.
以下是会话的配置Bootstrap.php
:
class Module
{
public function onBootstrap(MvcEvent $e)
{
// ...
$serviceManager = $e->getApplication()->getServiceManager();
$sessionManager = $serviceManager->get('session_manager_memcached');
$sessionManager->start();
Container::setDefaultManager($sessionManager);
// ...
}
public function getServiceConfig()
{
return array(
'factories' => array(
// ...
'session_manager_memcached' => function ($sm) {
$systemConfig = $sm->get('config');
$config = new SessionConfig;
$config->setOptions(array(
'phpSaveHandler' => 'memcache',
'savePath' => 'tcp://localhost:11211?timeout=1&retry_interval=15&persistent=1',
'cookie_httponly' => true,
'use_only_cookies' => true,
'cookie_lifetime' => 0,
'gc_maxlifetime' => 43200, // 12h
'remember_me_seconds' => 43200 // 12h
));
return new SessionManager($config);
},
// ...
);
}
}
Run Code Online (Sandbox Code Playgroud)
身份验证服务定义为
'authService' => function ($sm) {
$authService = new \Zend\Authentication\AuthenticationService;
$authService->setStorage(new \Zend\Authentication\Storage\Session('user_login'));
return $authService;
},
Run Code Online (Sandbox Code Playgroud)
然后在应用程序中的任何地方都需要检索或设置会话值我只需使用\Zend\Session\Container
如下:
$sessionContainer = new \Zend\Session\Container('ClientXYZ');
$sessionContainer['key1'] = $val1;
// or
$val2 = $sessionContainer['key2'];
Run Code Online (Sandbox Code Playgroud)
在使用来自会话的令牌的任何操作中,请求活动会话使用SSO,该会话包含来自auth源的PHPSESSID.在这个问题中描述这个很复杂.
此外,身份验证服务还使用相同的设置在memcached会话中存储用户身份(具有ACL的角色).显然,现在这是造成混乱的地方.显然,身份验证服务的会话存储过早地超时导致ACL不检索用户身份以检查导致SSO注销序列(但由于用户没有真正注销,SSO如上所述重定向用户).
我不确定我(也可以)在这里分享多少代码,也许你会立即引导我解决问题,或者只是问我一些问题.经过数小时的调试并试图找出问题后,我现在很无助.
在某个地方,我已经读过,一旦会话cookie的大小达到1MB ,memcached就会擦掉内存- 可能就是这种情况吗?对于用户身份,我们只保存一般用户信息和角色阵列,我猜这可能是最大的.高达几kb ...
编辑1:要消除所有猜测并节省您的时间,这里有一些事实(要密切关注):
PHPSESSID
在浏览器和服务器之间传输,它的值是memcached中存储数据的内存块的关键我将die
在PHP中实现一些s和return
JS部分中的s来捕捉会话被认为已经消失的时刻并进一步检查浏览器cookie,memcached数据等,并将更新你(除非有人提供解释和解决方案).
当使用memcached
as时session.save_handler
,会话的垃圾收集将不会被完成。
由于 Memcached 使用 TTL(生存时间)值,因此不需要垃圾回收。生存时间不够长而未达到 TTL 年龄的条目将被视为“新鲜”并将被使用。之后它将被视为“陈旧”并且将不再使用。最终 Memcached 会释放该条目所使用的内存,但这与 PHP 的会话垃圾回收无关。
事实上,session.gc_
本例中实际使用的唯一设置是session.gc_maxlifetime
,它将作为 TTL 传递到 Memcached。
简而言之:垃圾收集在您的情况下不是问题。
当您使用 Memcached 作为会话存储时,操作系统提供的任何手动清理磁盘上会话文件夹的 cronjobs(如 Ubuntu 那样)都将无效。Memcached 是内存存储,而不是磁盘存储。
简而言之:像这样的 cronjobs 在您的情况下不是问题。
您声明 SSO 服务器/权限与 SSO 客户端(应用程序本身)位于同一台计算机上,使用相同的 Web 服务器/PHP 配置,并且使用相同的 Memcached 实例。
这让我相信我们必须研究如何在应用程序中完成会话管理,因为这是 SSO 权限和客户端之间的唯一区别。换句话说:我们需要深入研究 Zend\Session。
免责声明:我曾专业开发过多个 Zend Framework 1 应用程序,但没有开发过任何 Zend Framework 2 应用程序。所以我在这里盲目飞行:)
我在您的配置中注意到的一件事是您已设置cookie_lifetime
为0
. 这实际上意味着“直到浏览器关闭”。这与设置为 12 小时并没有什么意义remember_me_seconds
,因为很多人会在此之前关闭浏览器。
我建议你cookie_lifetime
也设置为12小时。
另请注意,remember_me_seconds
仅在实际使用“记住我”功能时使用。换句话说: ifZend\Session\SessionManager::rememberMe()
被调用。
看看您使用 Memcached 作为会话存储实现的方式,以及我在该主题上可以找到的内容,我想说您所做的事情与似乎“首选方式”不同。
关于此主题的大多数资源建议使用Zend\Session\SaveHandler\Cache
( doc , api ) 作为保存处理程序,这使您能够使用Zend\Cache\Storage\Adapter\Memcached
( doc , api )。这使您可以更好地控制正在发生的事情,因为它不依赖于有限的memcached
会话保存处理程序。
我建议你尝试这个实现。如果它不能立即解决您的问题,至少还有更多关于该主题的资源可以找到。恕我直言,您找到解决方案的机会会更大。
归档时间: |
|
查看次数: |
1248 次 |
最近记录: |