php – 如何在Zend Framework中进行preDispatch转发?
发布时间:2020-12-13 22:00:18 所属栏目:PHP教程 来源:网络整理
导读:我想在检查用户是否在每个控制器中登录后,在preDispatch中使用_forward(). 这种情况非常简单:如果用户未登录,则应将其转发到同一控制器或另一个控制器中的loginAction. 这将导致无限循环,因为调度过程再次重新开始,再次调用preDispatch并且转发将再次启动所
|
我想在检查用户是否在每个控制器中登录后,在preDispatch中使用_forward().
这种情况非常简单:如果用户未登录,则应将其转发到同一控制器或另一个控制器中的loginAction. 这将导致无限循环,因为调度过程再次重新开始,再次调用preDispatch并且转发将再次启动所有内容. 我能想到的唯一解决方案是检查是否已在请求中设置loginAction. 所以我的问题是,复杂的开发人员将如何处理这个问题? UPDATE 解决方法
我使用Zend_Controller_Plugin和AuthController的组合来保护我的网站.它支持密码重置,强制密码更改和自动帐户锁定,因此具有中等复杂性.
请注意,我使用的是Doctrine,因此显然不能将其剪切并粘贴到您的应用程序中,但它应该以最小的更改运行.我删除了一些特定于我的应用程序的方法,但所有通用身份验证foo都在那里. 插入 <?php
class Hobo_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
if ('logout' != $request->getActionName()) {
if (! $request->getParam('force_password_change')
&& $this->_checkPasswordExpiry($auth->getIdentity()->username)
) {
$request->setParam('force_password_change',true);
$request->setModuleName('default')
->setControllerName('auth')
->setActionName('change-password');
}
}
} else {
// Defer more complex authentication logic to AuthController
if ('auth' != $this->getRequest()->getControllerName()) {
$redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$redirector->gotoSimple('restricted','auth');
}
}
}
protected function _checkPasswordExpiry($username)
{
// Look up user and return true if password is expired
}
}
AuthController <?php
class AuthController extends Zend_Controller_Action
{
public function init()
{
$this->_auth = Zend_Auth::getInstance();
$this->_errorMessenger = new Zend_Controller_Action_Helper_FlashMessenger();
$this->_errorMessenger->setActionController($this)->init();
$this->_errorMessenger->setNamespace('error');
$this->_noticeMessenger = new Zend_Controller_Action_Helper_FlashMessenger();
$this->_noticeMessenger->setActionController($this)->init();
$this->_noticeMessenger->setNamespace('notice');
$this->view->errors = $this->_errorMessenger->getMessages();
$this->view->notices = $this->_noticeMessenger->getMessages();
}
public function preDispatch()
{
if (! $this->_auth->hasIdentity()) {
if (! in_array($this->_request->getActionName(),array(
'logout','identify','forgot-password','reset-password','restricted'))
) {
$this->_redirect('/auth/restricted');
}
}
}
public function restrictedAction()
{
// Shows access restricted page
}
public function logoutAction()
{
$this->_auth->clearIdentity();
Zend_Session::destroy();
$this->_redirect('/');
}
public function identifyAction()
{
if ($this->_request->isPost()) {
$username = $this->_getParam('username');
$password = $this->_getParam('password');
if (empty($username) || empty($password)) {
$this->_flashError('Username or password cannot be blank.');
} else {
$user = new dUser();
$result = $user->login($username,$password);
if ($result->isValid()) {
$user->fromArray((array) $this->_auth->getIdentity());
if ($this->_getParam('changepass') || $user->is_password_expired) {
$this->_redirect('auth/change-password');
return;
}
$this->_doRedirect($user);
return;
} else {
$this->_doFailure($result->getIdentity());
}
}
}
$this->_redirect('/');
}
public function changePasswordAction()
{
if ($this->_request->isPost()) {
$username = $this->_auth->getIdentity()->username;
$formData = $this->_request->getParams();
if (empty($formData['password'])
|| empty($formData['new_password'])
|| empty($formData['confirm_password'])
) {
$this->_flashError('Password cannot be blank.');
$this->_redirect('auth/change-password');
} elseif ($formData['new_password'] !== $formData['confirm_password']) {
$this->_flashError('Password and confirmation do not match.');
$this->_redirect('auth/change-password');
} else {
$user = new dUser();
$result = $user->login($username,$formData['password']);
if ($result->isValid()) {
$user->updatePassword($username,$formData['new_password']);
$this->_flashNotice('Password updated successfully!');
$this->_redirect('/');
} else {
$this->_flashError('Invalid username or password!');
$this->_redirect('auth/change-password');
}
}
}
if ($this->_getParam('force_password_change')) {
$this->view->notice = 'Your password has expired. You must change your password to continue.';
}
}
public function forgotPasswordAction()
{
if ($this->_request->isPost()) {
// Pseudo-random uppercase 6 digit hex value
$resetCode = strtoupper(substr(sha1(uniqid(rand(),true)),6));
Doctrine_Query::create()
->update('dUser u')
->set('u.reset_code','?',array($resetCode))
->where('u.username = ?',array($this->_getParam('username')))
->execute();
$this->_doMail($this->_getParam('username'),$resetCode);
$this->_flashNotice("Password reset request received.");
$this->_flashNotice("An email with further instructions,including your <em>Reset Code</em>,has been sent to {$this->_getParam('username')}.");
$this->_redirect("auth/reset-password/username/{$this->_getParam('username')}");
}
}
public function resetPasswordAction()
{
$this->view->username = $this->_getParam('username');
$this->view->reset_code = $this->_getParam('reset_code');
if ($this->_request->isPost()) {
$formData = $this->_request->getParams();
if (empty($formData['username']) || empty($formData['reset_code'])) {
$this->_flashError('Username or reset code cannot be blank.');
$this->_redirect('auth/reset-password');
} elseif ($formData['new_password'] !== $formData['confirm_password']) {
$this->_flashError('Password and confirmation do not match.');
$this->_redirect('auth/reset-password');
} else {
$user = new dUser();
$result = $user->loginWithResetCode($formData['username'],$formData['reset_code']);
if ($result->isValid()) {
$user->updatePassword($result->getIdentity(),$formData['new_password']);
$user->fromArray((array) $this->_auth->getIdentity());
$this->_flashNotice('Password updated successfully!');
$this->_doRedirect($user);
} else {
$this->_doFailure($result->getIdentity());
$this->_redirect('auth/reset-password');
}
}
}
}
protected function _doRedirect($user)
{
$this->_helper->Redirector->gotoUserDefault($user);
}
protected function _flashError($message)
{
$this->_errorMessenger->addMessage($message);
}
protected function _flashNotice($message)
{
$this->_noticeMessenger->addMessage($message);
}
protected function _doFailure($username)
{
$user = Doctrine_Query::create()
->from('dUser u')
->select('u.is_locked')
->where('u.username = ?',array($username))
->fetchOne();
if ($user->is_locked) {
$this->_flashError('This account has been locked.');
} else {
$this->_flashError('Invalid username or password');
}
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
