1

在用户授权失败后,我想将他们转发回登录页面。目前 _forward 方法会导致 Zend 挂起并给出超时错误(超过 30 秒)。

登录页面的代码处理登录和注册表单,并转发到授权控制器:

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);
        }
    }
}

这工作正常并成功重定向到身份验证控制器。身份验证控制器的登录操作中的代码如下:

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);
    } 
}

我们很好地到达这里,成功的授权按预期工作。然而,在我的 else 语句中,将另一个转发回原始登录控制器(我希望填充用户名并回发错误消息)会导致程序挂起,尽管重定向工作正常。

我认为这可能是因为登录控制器正在重新检测发布数据并且我陷入了无限循环,但是删除 $formData 作为转发的最后一个参数并没有改变任何东西。

我还尝试了 $formData['errMsg'] = 'whatever' 上面的转发,然后检查密钥是否存在或是否在登录控制器中设置,但这也不会改变任何事情。

有趣的是,我收到的超时错误引用了 Auth DbTable 适配器:

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

关于可能发生的事情有什么想法吗?

4

2 回答 2

1

loginAction()我认为您在and之间无限循环indexAction()

查看调用助手forward()redirect()操作助手之间的区别。前者在forward()内部会改变$request->isDispatched() == false- 这意味着前端控制器将执行目标控制器操作而无需新的 HTTP 请求。

这样做的结果是$this->_request->isPost()永远如此true,因此$this->$form->isValid($formData)也将是真的,这意味着你在兜圈子。

我知道下面的方法与您的方法非常不同,但是我相信它是 Zend 1 控制器更传统的关注点分离。

// ... 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! 
  }

编辑详细说明:forward()是一个控制器动作助手。它的工作只是修改Zend_Controller_Request_Http实例。Zend_Controller_Request_Http该类是您$this->getRequest()在控制器中调用时返回的类。

Request 实例封装了对 的所有访问$_POST$_GET然后将其作为值存储在对象中。调用诸如$request->setParam('someparam', 123)设置或获取这些值而不是标准的直接访问$_POST['someparam']$_GET['someparam']

特殊情况是值modulecontroller和。这些是Dispatcher在尝试确定要实例化的正确控制器和要执行的操作方法时使用的键。actiondispatchedZend_Controller_Front

调度循环如何工作的简化示例:

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();

}
于 2013-10-07T11:34:15.123 回答
0

在 else 块中:

$this->_redirect($this->url(array('login' => $formData['username'], 'nameOfYourRoute'));

向您的路线添加了一个新的获取变量“登录”,并使用此变量填充您的表单登录。

于 2013-10-07T11:31:26.997 回答