Zend Framework 不活动后自动注销
我正在开发一个包含多个子应用程序的应用程序,我想在 30 分钟不活动后实现自动注销。我有一个 AuthController,其中登录和注销操作使用 Bootstrap.php 映射到自定义 /login 和 /logout 路由,以及前端控制器插件,如下所示:
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());
}
}
I'm working on an application that houses several sub applications and I'd like to implement an auto logout after 30 minutes of inactivity. I have an AuthController with login and logout actions mapped to custom /login and /logout routes using the Bootstrap.php as well as a front controller plugin that looks like this:
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);
}
}
I'm new to PHP and Zend, what exactly is happening to the session after 10 seconds? I have it set low for testing. What I'd like to have happen is if the time of the last request through the front controller plugin was greater than 30 minutes ago, destroy the session and log the user out and redirect them to /login.
I can see obviously that I'm not tracking the time of the last request but my hope was that the setExpirationSeconds would be refreshed each time the user has a request come through this preDispatch method.
Maybe a cookie needs used? I don't need to actually initiate a logout action, it can just be handled the next time the user makes a request, if they've not done anything in the last half hour the session is destroyed and they're logged out, meaning if I walk away for 45 minutes my screen still looks the same but if I click a link or try and submit a form I had up it sends me to /login. I can worry about some type of JS countdown warning later.
Edit: Here's my bootstrap if anyone wants to see it:
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());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当你调用
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 会话,并且可以让您的自定义身份验证类在不同的会话命名空间上设置不同的时间限制。希望我的回答对您的问题有所帮助,如果您对我所说的有疑问,请随时发表评论。
编辑:
我测试了以下代码,它在设定时间后成功使我的 Zend_Auth 身份过期。我用 60 秒对其进行了低测试,等待 60 秒加载页面后,我不再拥有身份并被“注销”。您可以将其添加到您的会话跟踪插件中。
When you call
Zend_Session::setExpirationSeconds(10)
, nothing is actually happening to the session after 10 seconds time per se.This call causes Zend_Session to store an internal value marking that session namespace for expiration at
time() + $seconds
from the time the call is made. Each time aZend_Session
starts, it checks to see if any session data is marked for expiration, and if so proceeds to check to see if the expiration time or hop count has passed. If that is the case, then the session data in question is unset at initialization, and is therefore no longer accessible by your application.If you make this call at the beginning of every request, it should continue to prolong the life of the session by that many seconds on each page load.
Keep in mind that if the session settings in
php.ini
are set to expire the session after 15 minutes, setting a namespace to expire after 60 minutes will not override PHP's session lifetime of 15 minutes. You can make such adjustments to PHP's session directives in yourapplication.ini
file.Setting an expiration on the namespace also has the advantage of automatically removing some session data without having to destroy the entire session.
I don't know the specifics of your application, but you could use the plugin to check and see if they are logged out and forward the request to your login page. You could check for a valid login after creating the namespace, but you also would want to make sure that the current request wasn't a login attempt. Or you could just defer checking for valid login in the plugin and let your ACL handle that later at the controller level.
You may also want to look into Zend_Auth which you can use to persist an identity in the session. The identity can be anything from a simple boolean value indicating if they are logged in, to a full blown user object that implements
Zend_Acl_Role_Interface
. Zend Auth is also easily extended so you can have multiple Zend_Auth sessions active at the same time by using different namespaces for each instance, and could have your custom auth class set different time limits on different session namespaces.I hope that helps answer your question, feel free to comment if you have questions on what I said.
EDIT:
I tested the following code and it successfully expired my Zend_Auth identity after the set time. I tested it low with 60 seconds and after waiting 60 seconds to load the page, I no longer had and identity and was "logged out". You could add this to your session track plugin.