2010年2月28日 星期日

Zend_Auth、Zend_Acl的使用實例(在Action中使用Acl)

數據庫表:

CREATE TABLE `user` (

`uid` SMALLINT( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 20 ) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL ,
`password` CHAR( 32 ) NOT NULL ,
`role` ENUM( 'user', 'staff', 'admin' ) NOT NULL ,
`truename` VARCHAR( 20 ) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL ,
INDEX ( `role` , `truename` ) ,
UNIQUE (

`username`

)

) ENGINE = MYISAM CHARACTER SET gbk COLLATE gbk_chinese_ci COMMENT = '用戶表';

在數據庫中存儲了一個role字段(枚舉類型),以保存用戶角色信息!

add(new Zend_Acl_Resource('Default'));
$acl->add(new Zend_Acl_Resource('News'));
//上面對應我的兩個module,一個Default,一個News
$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('user'), 'guest');
$acl->addRole(new Zend_Acl_Role('staff'), 'user');
$acl->addRole(new Zend_Acl_Role('admin'));

$acl->allow('guest', array('Default', 'News'), 'view');
$acl->allow('user', array('Default', 'News'), array('reply', 'download'));
$acl->allow('staff', array('Default', 'News'), array('delete', 'update'));
$acl->allow('admin');

//驗證權限,如果沒有登錄則以遊客身份登錄
$auth = Zend_Auth::getInstance();
if(!$auth->hasIdentity())
{
$auth->getStorage()->write((object)array('username' => 'Guest',
'role' => 'guest',
'truename' => '遊客'));
}
$router = new Zend_Controller_Router_Rewrite();
//$router->addRoute('root',new Zend_Controller_Router_Route('/',array('module' =>'News', 'controller' => 'Index', 'Action' => 'index'))); 也是給出默認控制器的
$front = Zend_Controller_Front::getInstance()->setControllerDirectory(array(
'default' => './Default/Controllers',
'News' => './News/Controllers'
))
->setRouter($router)
->setParam('Zend_Acl', $acl)
->setParam('Zend_Auth', $auth)
->setBaseUrl('/zf/index.php')
->setParam('noViewRenderer', true)
->setParam('useDefaultControllerAlways',true)
->throwExceptions(true)->returnResponse(false)
->dispatch();
?>

在Action中使用Zend_Acl(Default模塊中的IndexController,訪問他的downloadAction):

name = '張心靈';
$view->title = '測試';
$view->setScriptPath('./Default/Views/Index');
$view->addScriptPath('./Default/Views');
$this->getResponse()->appendBody($view->render('Index.phtml'));
}
public function downloadAction()
{
$acl = $this->getInvokeArg('Zend_Acl');
if(!$acl->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, 'Default', 'download')) $this->getResponse()->appendBody('訪問不合法');
else $this->getResponse()->appendBody('合法訪問');
}
}

測試地址:http://localhost/zf/index.php/index/download

當然,據稱更好的辦法是在 preDispatch 方法中控制權限

測試代碼如下:

getInvokeArg('Zend_Acl')->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, ucfirst($this->getRequest()->getModuleName()), $this->getRequest()->getActionName()))
$this->_forward('index', 'user', 'Default');
}
public function indexAction()
{
$view = new Zend_View;
$view->name = '張心靈';
$view->title = '測試';
$view->setScriptPath('./Default/Views/Index');
$view->addScriptPath('./Default/Views');
$this->getResponse()->appendBody($view->render('Index.phtml'));
}
public function downloadAction()
{
$acl = $this->getInvokeArg('Zend_Acl');
if(!$acl->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, 'Default', 'download')) $this->getResponse()->appendBody('訪問不合法');
else $this->getResponse()->appendBody('合法訪問');
}
}

執行結果還是OK的!不過就是感覺在 preDispatch 中控制權限比較呆板啦!

運行的Perfect!(感謝CCTV、感謝Channal V................)

很簡單的是,您可以將 訪問不合法那句 改為 _froward 等等,讓用戶登錄就行了,看起來Zend Framework使用還是蠻方便的(除了Zend_XmlRpc,那麼大個Bug,居然這麼就了都沒修復)

沒有留言: