Поскольку вы очень заинтересованы в сохранении состояния запроса POST, а также потому, что я долгое время играл с этой же идеей, как насчет чего-то вроде следующего. Это все еще непроверено, поэтому я хотел бы услышать результат того, действительно ли установка сохраненного запроса работает так, как ожидалось. (Извините, чтобы проверить это в данный момент).
В вашем конфиге ini:
resources.frontController.plugins[] = "Cas_Controller_Plugin_Authenticator"
Вот плагин:
class Cas_Controller_Plugin_Authenticator
extends Zend_Controller_Plugin_Abstract
{
public function routeStartup( Zend_Controller_Request_Abstract $request )
{
if( Zend_Auth::getInstance()->hasIdentity() )
{
if( null !== $request->getParam( 'from-login', null ) && Zend_Session::namespaceIsset( 'referrer' ) )
{
$referrer = new Zend_Session_Namespace( 'referrer' );
if( isset( $referrer->request ) && $referrer->request instanceof Zend_Controller_Request_Abstract )
{
Zend_Controller_Front::getInstance()->setRequest( $referrer->request );
}
Zend_Session::namespaceUnset( 'referrer' );
}
}
else
{
$referrer = new Zend_Session_Namespace( 'referrer' );
$referrer->request = $this->getRequest();
return $this->_redirector->gotoRoute(
array(
'module' => 'default',
'controller' => 'user',
'action' => 'login'
),
'default',
true
);
}
}
}
Плагин должен проверить routeStartup
, аутентифицирован ли пользователь;
- Если пользователь НЕТ: он сохраняет текущий объект запроса в сеансе и перенаправляет на
UserController::loginAction()
. (см. ниже)
- Если пользователь IS: он извлекает сохраненный объект запроса из сеанса (если он доступен, И, если пользователь только что вошел в систему) и заменяет текущий объект запроса в frontController (который, как мне кажется, должен быть подключен к маршрутизатору).
В общем, если вам нужна большая гибкость в определении того, какие параметры модуля / контроллера / действия нуждаются в аутентификации и авторизации (что, я полагаю, вам нужно), вы, вероятно, захотите перенести некоторые проверки на другой хук, чем routeStartup
: а именно routeShutdown
, dispatchLoopStartup
или preDispatch
. Потому что к тому времени должны быть известны параметры действий. В качестве дополнительной меры безопасности вы также можете сравнить параметры действия (модуль / контроллер / действие) исходного запроса и запрос на замену, чтобы определить, имеете ли вы дело с правильным сохраненным запросом.
Кроме того, вам может потребоваться установить $request->setDispatched( false )
для нового объекта запроса, в некоторых или во всех хуках. Хотя не совсем уверен: см. документы .
А вот пример контроллера входа в систему:
class UserController
extends Zend_Controller_Action
{
public function loginAction()
{
$request = $this->getRequest();
if( $request->isPost() )
{
if( someAuthenticationProcessIsValid() )
{
if( Zend_Session::namespaceIsset( 'referrer' ) )
{
$referrer = new Zend_Session_Namespace( 'referrer' );
if( isset( $referrer->request ) && $referrer->request instanceof Zend_Controller_Request_Abstract )
{
return $this->_redirector->gotoRoute(
array(
'module' => $referrer->request->getModuleName(),
'controller' => $referrer->request->getControllerName(),
'action' => $referrer->request->getActionName(),
'from-login' => '1'
),
'default',
true
);
}
}
// no referrer found, redirect to default page
return $this->_redirector->gotoRoute(
array(
'module' => 'default',
'controller' => 'index',
'action' => 'index'
),
'default',
true
);
}
}
// GET request or authentication failed, show login form again
}
}
В целях безопасности может потребоваться установить переменную сеанса с интервалом истечения 1 вместо переменной строки запроса from-login.
Наконец, сказав все это; Возможно, вы захотите тщательно подумать, действительно ли вы хотите этого поведения в первую очередь. POST-запросы, как вы, конечно, знаете, обычно запрещают чувствительные операции по изменению состояния (создание, удаление и т. Д.). Я не уверен, что пользователи обычно ожидают такого поведения сразу после входа в систему (после истечения срока их сессии). Кроме того, вы можете подумать о возможных сценариях, в которых это может привести к неожиданному поведению самого приложения. Сейчас я не могу придумать каких-либо подробностей, но если бы я больше об этом думал, я уверен, что смогу придумать что-нибудь.
НТН
EDIT
Забыл добавить правильные действия перенаправления после входа в систему