doucan957495 2013-10-07 11:02
浏览 47
已采纳

验证失败后Zend _forward不起作用(Zend Framework 1)

After a user fails authorisation I'd like to forward them back to the login page. Currently the _forward method causes Zend to hang and give a time out error (30 seconds exceeded).

The code for the login page handles both a login and signup form, and forwards to the authorisation controller:

public function indexAction() {

    if ($this->_request->isPost()) {
        $formData = $this->_request->getPost();

        if (array_key_exists('signUp', $formData)) {
            $authAction = 'signup';
            $form = 'signupForm';
        } elseif (array_key_exists('logIn', $formData)) {
            $authAction = 'login';
            $form = 'loginForm';
        }

        if ($this->$form->isValid($formData)) {
            $this->_forward($authAction, 'user-auth', null, $formData);
        } else {
            $this->$form->populate($formData);
        }
    }
}

This works fine and redirects to the auth controller successfully. The code inside the login action of the auth controller is as such:

public function loginAction() {
    $formData = $this->_request->getPost();

    $authAdapter = new My_Auth_Adapter();
    $authAdapter->setTableName('user')
                ->setIdentity($formData['username'])
                ->setCredential($formData['password'])
                ->setIdentityColumn('username')
                ->setCredentialColumn('password');
    $result = $authAdapter->authenticate();

    if ($result->isValid()) {
        // success, all good
    } else {
        $this->_forward('index', 'login', 'default', $formData);
    } 
}

We arrive here fine, and a successful authorisation works as expected. However in my else statement placing another forward back to the original login controller (I wish to populate the username as well as post back an error message) causes the program to hang, although a redirect works fine.

I thought it may be because the login controller is re-detecting the post data and I'm getting caught in an infinite loop, but removing the $formData as the last argument of the forward doesn't change anything.

I've also tried $formData['errMsg'] = 'whatever' above the forward and then checking if the key exists or if it is set in the login controller, but that doesn't change a thing either.

Interestingly, the time out error I receive references the Auth DbTable Adapter:

Fatal error: Maximum execution time of 30 seconds exceeded in /Applications/MAMP/MampServer/mysite/library/Zend/Auth/Adapter/DbTable.php on line 174

Any ideas as to what may be happening?

  • 写回答

2条回答 默认 最新

  • douhao3562 2013-10-07 11:34
    关注

    I think you are infinity looping between loginAction() and indexAction().

    Check out the difference between the calls to forward() and redirect() action helpers. The former, forward() internally will change the $request->isDispatched() == false - This means that the front controller will execute the targeted controller action without a new HTTP request.

    The outcome of this is that $this->_request->isPost() will always be true and therefore $this->$form->isValid($formData) again will also be true, meaning your going around in circles.

    I know the below is a very different to your approach, however I believe it is a more conventional separation of concerns for Zend 1 controllers.

    // ... SomeController.php
    
      public function getLoginForm();
    
      public function getSignupForm();
    
      protected function authenticate($username, $password) 
      {
        $authAdapter = new My_Auth_Adapter();
        $authAdapter->setTableName('user')
                    ->setIdentity($username)
                    ->setCredential($password)
                    ->setIdentityColumn('username')
                    ->setCredentialColumn('password');
        $result = $authAdapter->authenticate();
    
        return ($result->isValid()) ? true : false;
      }
    
      public function indexAction()
      {
        $form = $this->getLoginForm();
        $request = $this->getRequest();
    
        if ($request->isPost()) {
          if ($form->isValid($request->getPost())) {
    
            if ($this->authenticate($form->getValue('username'), $form->getValue('username'))) {
              $this->redirect('/members'); // Successfully logged in
            }
          }
        }
        $this->view->form = $form;
      }
    
      public function signupAction()
      {
        // stuff only for signups! 
      }
    

    Edit To elaborate: forward() is a controller action helper. Its job is simply to modify the Zend_Controller_Request_Http instance. The Zend_Controller_Request_Http class is the one returned when you call $this->getRequest() within a controller.

    The Request instance encapsulates all access to $_POST, $_GET and stores then as values within the object. Calls such as $request->setParam('someparam', 123) set or get these values rather than the standard direct access to $_POST['someparam'] or $_GET['someparam'].

    The special case is with the values module,controller,action and dispatched. These are the key's used by the Zend_Controller_Front and the Dispatcher when trying to determine the correct controller to instantiate and action method to execute.

    A simplified example of how the dispatch loop works:

    while(! $request->isDispatched()) {
    
      $request->setDispatched(true);
    
      // If at any point here we change setDispatched(true)
      // perhaps in a controller action with a call to forward()
      // then the whole dispatch loop will be called again
      // perhaps creating a different controller
    
      $controllerName = $request->getControllerName();
      $actionName = $request->getActionName();
    
      $controller = new $controllerName();
      $controller->$actionName();
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog