Zend Framework在不活动后自动注销

时间:2012-02-18 22:06:49

标签: php zend-framework session

我正在开发一个包含多个子应用程序的应用程序,我想在30分钟不活动后实现自动注销。我有一个AuthController,其登录和注销操作使用Bootstrap.php以及前导控制器插件映射到自定义/登录和/登出路由,如下所示:

class Plugin_SessionTrack extends Zend_Controller_Plugin_Abstract {

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {  

        $employeeSession = new Zend_Session_Namespace('employeeSession');
        $employeeSession->setExpirationSeconds(10);

    }
}

我是PHP和Zend的新手,10秒后会话究竟发生了什么?我把它设置为低测试。我想要发生的事情是,如果通过前端控制器插件的最后一次请求的时间超过30分钟,则销毁会话并将用户注销并将其重定向到/ login。

我可以清楚地看到我没有跟踪上次请求的时间,但我希望每次用户通过此preDispatch方法发出请求时都会刷新setExpirationSeconds。

可能需要使用Cookie吗?我不需要实际启动注销操作,它可以在用户下次发出请求时进行处理,如果他们在过去半小时内没有做任何事情会话被销毁并且他们已经注销,这意味着如果我走开45分钟,我的屏幕看起来仍然相同,但如果我点击一个链接或尝试提交一个表格,我就把它发送给/ login。我稍后会担心某种类型的JS倒计时警告。

编辑:如果有人想看到它,这是我的引导程序:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    /**
     * Custom routes:
     * 
     * /login
     * /logout
     */
    protected function _initRoutes()
    {

        $router = Zend_Controller_Front::getInstance()->getRouter();

        $loginRoute = new Zend_Controller_Router_Route('login', array('controller' => 'auth', 'action' => 'login'));

        $logoutRoute = new Zend_Controller_Router_Route('logout', array('controller' => 'auth', 'action' => 'logout'));

        $routesArray = array('login' => $loginRoute, 'logout' => $logoutRoute);

        $router->addRoutes($routesArray);

    }

    protected function _initPlugins()
    {

        $frontController = Zend_Controller_Front::getInstance();
        $frontController->registerPlugin(new Plugin_SessionTrack());

    }
}

1 个答案:

答案 0 :(得分:11)

当你致电Zend_Session::setExpirationSeconds(10)时,在10秒的时间内,会话实际上没有发生任何事情。

此调用导致Zend_Session存储一个内部值,标记该会话命名空间从调用时起time() + $seconds到期。每次Zend_Session启动时,它都会检查是否有任何会话数据标记为过期,如果是,则继续检查过期时间或跳数是否已过。如果是这种情况,则会在初始化时取消设置相关的会话数据,因此您的应用程序无法再访问该数据。

如果您在每个请求开始时进行此调用,则应在每次加载页面时继续延长会话的生命周期。

请记住,如果php.ini中的会话设置设置为在15分钟后使会话过期,则将命名空间设置为在60分钟后过期将不会覆盖PHP的会话生存期15分钟。您可以在application.ini文件中对PHP的会话指令进行此类调整。

在命名空间上设置过期还具有自动删除某些会话数据而不必销毁整个会话的优势。

我不知道您的应用程序的具体细节,但您可以使用该插件检查并查看它们是否已注销并将请求转发到您的登录页面。您可以在创建命名空间后检查有效登录,但您还希望确保当前请求不是登录尝试。或者你可以推迟检查插件中的有效登录,让你的ACL稍后在控制器级别处理。

您可能还想查看可用于在会话中保留身份的Zend_Auth。标识可以是指示它们是否已登录的简单布尔值,以及实现Zend_Acl_Role_Interface的完整用户对象。 Zend Auth也很容易扩展,因此您可以通过为每个实例使用不同的命名空间来同时激活多个Zend_Auth会话,并且可以让您的自定义auth类在不同的会话命名空间上设置不同的时间限制。

我希望这有助于回答您的问题,如果您对我所说的内容有疑问,请随时发表评论。

修改

我测试了以下代码,并在设定的时间后成功过期了我的Zend_Auth身份。我用60秒测试它低,等待60秒后加载页面,我不再拥有身份并被“注销”。您可以将其添加到会话跟踪插件中。

<?php
$auth = Zend_Auth::getInstance();

if ($auth->hasIdentity()) { // user is logged in
    // get an instance of Zend_Session_Namespace used by Zend_Auth
    $authns = new Zend_Session_Namespace($auth->getStorage()->getNamespace());

    // set an expiration on the Zend_Auth namespace where identity is held
    $authns->setExpirationSeconds(60 * 30);  // expire auth storage after 30 min
}