异步会干扰我的ACL插件

时间:2009-07-22 16:36:28

标签: php zend-framework plugins acl

我刚创建了一个插件,可以与我的网站一起使用,以确保在执行操作之前对用户进行了身份验证。这是插件:

class Booze_Plugin_AclPlugin extends Zend_Controller_Plugin_Abstract{

public function preDispatch(Zend_Controller_Request_Abstract $request)
{
    $auth = Booze_Permissions_Auth::getInstance();
    $acl = Zend_Registry::get('acl');

    if(!$auth->hasIdentity())
    {
        $role = Booze_Permissions_Roles::GUEST;
    }
    else
    {
        $role = $auth->getUser()->role;
    }

    $resource = $request->getControllerName();
    $privilege = $request->getActionName();

    if(!$acl->isAllowed($role, $resource, $privilege))
    {
        Booze_Log::log("ACLPlugin: Sent to login");

        $request->setControllerName('login');
        $request->setActionName('index');
        $request->setDispatched(false);
    }
}

}

它似乎适用于非异步的页面。但是,我有一个控制器谁的工作是执行异步功能。这是控制器(相关部分):

class AsyncController extends Zend_Controller_Action{

public function init()
{

    if(!$this->getRequest()->isXMLHttpRequest())
    {
        $this->_forward('index', 'index');
    }

    $this->_helper->viewRenderer->setNoRender();
    $this->_helper->getHelper('layout')->disableLayout();
 }

 public function addcommentAction()
 {
    $params = $this->getDecoded('comment', true);
    $params_array = (array)$params;

    $auth = Booze_Permissions_Auth::getInstance();
    if(!$auth->hasIdentity())
    {
        $this->getResponse()->setBody("Guest");
    }

    $params_array['user_id'] = $auth->getUser('user_id');
    $params_array['store_id'] = Booze_Storage::get('store_id');

    if($this->comments->insertComment($params_array))
    {
        $this->getResponse()->setBody("success");
    }
    else
    {
        $this->getResponse()->setBody("CommentFail");
    }
 }

当我调用异步函数addcommentAction时,即使以guest身份登录,也不会将我带到登录控制器。但是,我从firebug中发现,它正在为登录控制器发送html,但只是没有出现在我的浏览器中。在我看来,这必须与async控制器在init中关闭视图渲染和布局这一事实有关。我已经尝试搞乱它,并且无法找出一种可靠的方法来确保插件中的重定向始终呈现,并显示自己。任何帮助都会很出色。

2 个答案:

答案 0 :(得分:0)

你试过做一个header()重定向吗? 像:

$this->_helper->getHelper('Redirector')->setCode(303)
                                       ->setExit(false)
                                       ->setGotoSimple('index', 'login');

编辑:正如您在评论中所说,您确实获得了正确的html(登录) - 如果请求是异步的,您无法检查登录操作并返回一些错误代码,然后您在javascript请求中处理码?

答案 1 :(得分:0)

我会添加插件的!isAllowed()部分:

if(!$acl->isAllowed($role, $resource, $privilege))
{
    if(!$this->getRequest()->isXMLHttpRequest())
    {
        //@todo getResponse
        $response->setBody(Zend_Json::encode(array('result'=>'fail', 'reason'=>'Need login');
        $response->sendResponse();
        exit;
    }

    Booze_Log::log("ACLPlugin: Sent to login");

    $request->setControllerName('login');
    $request->setActionName('index');
    $request->setDispatched(false);
}

当结果为“失败”时,与异步页面句柄相比,包含JSON。