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 请问一下这个运行结果是怎么来的
  • ¥15 这个复选框什么作用?
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1
  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下