仅在用户登录时设置会话 cookie

Set session cookie only when user is logged in

我正在构建一个基于 ZF3 的应用程序,我正在尝试让会话 cookie 仅在用户成功登录后 设置。并将其删除注销。

ZF3 Session好像没有这个功能,至少我在zend-session configuration文档里没找到

现在,当打开任何页面但未找到会话 cookie 时,框架会创建 PHPSESSID 会话 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 会导致问题。

虽然基本实现有效,但我仍在研究副作用。