异步干扰我的 ACL 插件

发布于 2024-07-27 12:37:49 字数 2084 浏览 3 评论 0原文

我刚刚创建了一个插件来配合我的网站,以确保用户在执行操作之前经过身份验证。 这是插件:

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 时,即使以访客身份登录,它也不会带我进入登录控制器。 然而,我从 firebug 中发现,它正在发送登录控制器的 html,但只是没有显示在我的浏览器中。 在我看来,这一定与异步控制器在 init 中关闭视图渲染和布局这一事实有关。 我尝试过弄乱它,但无法找到可靠的方法来确保插件中的重定向始终呈现并显示自身。 任何帮助都会非常出色。

I just created a plugin to go with my site to make sure a user is authenticated before performing an action. This is the plugin:

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

}

It seems to work for pages that aren't async. However, I have a controller who's job is to perform async functions. This is that controller (relevant parts):

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

When I call the async function addcommentAction, even when signed in as a guest, it does not take me to the login controller. I have, however, found out from firebug, that it IS sending the html for the login controller, but just isn't showing up in my browser. In my mind this must have something to do with the fact that the async controller has, in the init, turned off view rendering and the layout. I've tried messing with it, and can't figure out a reliable way to make sure the redirect in the plugin always renders, and shows itself. Any help would be outstanding.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蘑菇王子 2024-08-03 12:37:49

我会在插件的 !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);
}

当结果为“失败”时,在异步页面上处理 incloming JSON。

I would add in the !isAllowed() part of plugin this:

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

Than on your async page handle incloming JSON when result is 'fail'.

梦中的蝴蝶 2024-08-03 12:37:49

您是否尝试过进行 header() 重定向?
像:

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

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

have you tried to do a header() redirect?
like:

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

Edit: As you sayd in your comment, you do get the correct html (login) - couldn't you check in the login action, if the request is async and return some error code that you then handle in your javascript request code?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文