Zend Framework 1.12 plugin for checking “Authoriza

2019-08-05 19:12发布

I'm writing REST api using Zend Framework 1.12. I want to check "Authorization" header in controller plugin.

I put code in the preDispatch action of the plugin

$authorizationHeader    =   $request->getHeader('Authorization');
if(empty($authorizationHeader)) {
    $this->getResponse()->setHttpResponseCode(400);
    $this->getResponse()->setBody('Hello');
    die(); //It doesn't work
}

The problem is that after it controller's action is still being called. I tried 'die()', 'exit'. My question is how to return response from plugin and do not call controller's action.

2条回答
祖国的老花朵
2楼-- · 2019-08-05 19:16

Did a similar REST API with Zend several weeks ago with this approach:

Class Vars/Consts:

protected $_hasError = false;
const HEADER_APIKEY = 'Authorization';

My preDispatch:

public function preDispatch()
{
    $this->_apiKey = ($this->getRequest()->getHeader(self::HEADER_APIKEY) ? $this->getRequest()->getHeader(self::HEADER_APIKEY) : null);

    if (empty($this->_apiKey)) {
        return $this->setError(sprintf('Authentication required!'), 401);
    }

    [...]

}

My custom setError Function:

private function setError($msg, $code) {
    $this->getResponse()->setHttpResponseCode($code);
    $this->view->error = array('code' => $code, 'message' => $msg);
    $this->_hasError = true;

    return false;
}

Then simply check if a error has been set inside your functions:

public function yourAction()
{
    if(!$this->_hasError) {

    //do stuff

    }
}

If you're using contextSwitch and JSON, then your array with errors will be automatically returned & displayed, if an error occours:

public function init()
{
    $contextSwitch = $this->_helper->getHelper('contextSwitch');
    $this->_helper->contextSwitch()->initContext('json');

    [...]

}

Hope this helps

查看更多
爷、活的狠高调
3楼-- · 2019-08-05 19:32

Since checking headers is typically a low level request operation, you could do the header verification and then throw an exception if not valid in dispatchLoopStartup of the plugin. Then in your error controller, return the appropriate response. This would prevent the action from being dispatched/run and could be applied to any controller/action without modifying any controller code.

Controller plugin:

class AuthHeader extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(\Zend_Controller_Request_Abstract $request)
    {
        // Validate the header.
        $authorizationHeader = $request->getHeader('Authorization');

        if ($invalid) {
            throw new Zend_Exception($error_message, $error_code);
        }
    }
}

Error handler:

class ErrorController extends Zend_Controller_Action
{
    public function init()
    {
        // Enable JSON output for API originating errors.
        if ($this->isApiRequest($this->getRequest())) {
            $contextSwitch = $this->_helper->getHelper('contextSwitch');
            $contextSwitch->addActionContext('error', 'json')
                          ->setAutoJsonSerialization(true)
                          ->initContext('json');
        }
    }

    public function errorAction()
    {
        // Handle authorization header errors
        // ...

        // Handle errors
        // ...
    }

    public function isApiRequest($request)
    {
        // Determine if request is an API request.
        // ...
    }
}
查看更多
登录 后发表回答