仅在用户登录时设置会话 cookie
Set session cookie only when user is logged in
我正在构建一个基于 ZF3 的应用程序,我正在尝试让会话 cookie 仅在用户成功登录后 设置。并将其删除注销。
ZF3 Session好像没有这个功能,至少我在zend-session configuration文档里没找到
现在,当打开任何页面但未找到会话 cookie 时,框架会创建 PHPSESSID
会话 cookie(默认名称)。
在用户实际登录之前,该 cookie 对我的应用程序完全没有用,因为我不需要为访客记住会话数据。
我希望改变这种行为,以便会话 cookie 生成模型是这样的:
- 在进行有效登录之前不要创建会话 cookie。只需将会话视为一个新会话,但跳过创建 cookie。
- 在用户登录时创建会话 cookie,其生命周期在配置中指定。
- 当用户注销时销毁会话 cookie。
不胜感激。
万一有人问类似的问题。
经过一番摆弄,我找到了解决方案,但也发现了一些不良副作用。
解决方案
正如 Raphioly-San 在问题评论中指出的那样,您需要访问会话以确定用户是否已登录。这意味着您需要每次都启动会话。这反过来会生成会话 cookie。
因此,唯一的解决方案是在应用程序结束时销毁会话 cookie(如果用户未登录),并且根本不阻止会话 cookie 的生成。
实施
引导模块时,为 MvcEvent::EVENT_FINISH
添加一个侦听器,如果没有用户登录,则在应用程序退出时销毁当前会话。
namespace Application;
class Module
{
public function onBootstrap(MvcEvent $event) {
$event->getApplication()
->getEventManager()
->attach(
MvcEvent::EVENT_FINISH,
function() use ($event){
// Stop if a user is logged in
$userLoggedIn = $event->getApplication()->getServiceManager()->get(AuthenticationService::class)->hasIdentity();
if ($userLoggedIn) {
return;
}
// Destroy session cookie
// Note: this is not the most elegant solution, but it will suffice for this example
$params = session_get_cookie_params();
setcookie(session_name(), '', 1, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
session_destroy();
session_write_close();
},
-999
);
}
}
副作用
销毁会话 cookie 至少会破坏 Flash Messenger 组件,当它用于访客时。
其他组件也可能无法正常工作。
结论
我应服务器管理员的要求研究了这个解决方案,因为在使用 Varnish 缓存系统时 cookie 会导致问题。
虽然基本实现有效,但我仍在研究副作用。
我正在构建一个基于 ZF3 的应用程序,我正在尝试让会话 cookie 仅在用户成功登录后 设置。并将其删除注销。
ZF3 Session好像没有这个功能,至少我在zend-session configuration文档里没找到
现在,当打开任何页面但未找到会话 cookie 时,框架会创建 PHPSESSID
会话 cookie(默认名称)。
在用户实际登录之前,该 cookie 对我的应用程序完全没有用,因为我不需要为访客记住会话数据。
我希望改变这种行为,以便会话 cookie 生成模型是这样的:
- 在进行有效登录之前不要创建会话 cookie。只需将会话视为一个新会话,但跳过创建 cookie。
- 在用户登录时创建会话 cookie,其生命周期在配置中指定。
- 当用户注销时销毁会话 cookie。
不胜感激。
万一有人问类似的问题。
经过一番摆弄,我找到了解决方案,但也发现了一些不良副作用。
解决方案
正如 Raphioly-San 在问题评论中指出的那样,您需要访问会话以确定用户是否已登录。这意味着您需要每次都启动会话。这反过来会生成会话 cookie。
因此,唯一的解决方案是在应用程序结束时销毁会话 cookie(如果用户未登录),并且根本不阻止会话 cookie 的生成。
实施
引导模块时,为 MvcEvent::EVENT_FINISH
添加一个侦听器,如果没有用户登录,则在应用程序退出时销毁当前会话。
namespace Application;
class Module
{
public function onBootstrap(MvcEvent $event) {
$event->getApplication()
->getEventManager()
->attach(
MvcEvent::EVENT_FINISH,
function() use ($event){
// Stop if a user is logged in
$userLoggedIn = $event->getApplication()->getServiceManager()->get(AuthenticationService::class)->hasIdentity();
if ($userLoggedIn) {
return;
}
// Destroy session cookie
// Note: this is not the most elegant solution, but it will suffice for this example
$params = session_get_cookie_params();
setcookie(session_name(), '', 1, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
session_destroy();
session_write_close();
},
-999
);
}
}
副作用
销毁会话 cookie 至少会破坏 Flash Messenger 组件,当它用于访客时。
其他组件也可能无法正常工作。
结论
我应服务器管理员的要求研究了这个解决方案,因为在使用 Varnish 缓存系统时 cookie 会导致问题。
虽然基本实现有效,但我仍在研究副作用。