PHPEye开源社区 » Zend Framework 使用讨论 » Zend_Auth、Zend_Acl是这么用的么?(ZF RC2测试通过)
《Programming PHP》第二版上市
2007-6-16 17:04 wps2000
Zend_Auth、Zend_Acl是这么用的么?(ZF RC2测试通过)

我没有开Url重写的~!(总是给老师做,控制不了服务器,开不了)

引导文件:
[color=#000000][font=NSimsun][color=#0000bb]<?php
error_reporting[/color][color=#007700]([/color][color=#0000bb]E_ALL[/color][/font][font=NSimsun][color=#007700]);
require [/color][color=#dd0000]'./Zend/Loader.php'[/color][/font][font=NSimsun][color=#007700];
function [/color][color=#0000bb]__autoload[/color][color=#007700]([/color][color=#0000bb]$class[/color][/font][font=NSimsun][color=#007700])
{
    [/color][color=#0000bb]Zend_Loader[/color][color=#007700]::[/color][color=#0000bb]loadClass[/color][color=#007700]([/color][color=#0000bb]$class[/color][/font][color=#007700][font=NSimsun]);
}
[/font][/color][font=NSimsun][color=#ff8000]//初始化访问控制连
[/color][color=#0000bb]$acl [/color][color=#007700]= new [/color][color=#0000bb]Zend_Acl[/color][/font][font=NSimsun][color=#007700];
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]add[/color][color=#007700](new [/color][color=#0000bb]Zend_Acl_Resource[/color][color=#007700]([/color][color=#dd0000]'Default'[/color][/font][font=NSimsun][color=#007700]));
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]add[/color][color=#007700](new [/color][color=#0000bb]Zend_Acl_Resource[/color][color=#007700]([/color][color=#dd0000]'News'[/color][/font][color=#007700][font=NSimsun]));
[/font][/color][font=NSimsun][color=#ff8000]//上面对应我的两个module,一个Default,一个News
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]addRole[/color][color=#007700](new [/color][color=#0000bb]Zend_Acl_Role[/color][color=#007700]([/color][color=#dd0000]'guest'[/color][/font][font=NSimsun][color=#007700]));
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]addRole[/color][color=#007700](new [/color][color=#0000bb]Zend_Acl_Role[/color][color=#007700]([/color][color=#dd0000]'user'[/color][color=#007700]), [/color][color=#dd0000]'guest'[/color][/font][font=NSimsun][color=#007700]);
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]addRole[/color][color=#007700](new [/color][color=#0000bb]Zend_Acl_Role[/color][color=#007700]([/color][color=#dd0000]'staff'[/color][color=#007700]), [/color][color=#dd0000]'user'[/color][/font][font=NSimsun][color=#007700]);
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]addRole[/color][color=#007700](new [/color][color=#0000bb]Zend_Acl_Role[/color][color=#007700]([/color][color=#dd0000]'admin'[/color][/font][font=NSimsun][color=#007700]));

[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]allow[/color][color=#007700]([/color][color=#dd0000]'guest'[/color][color=#007700], array([/color][color=#dd0000]'Default'[/color][color=#007700], [/color][color=#dd0000]'News'[/color][color=#007700]), [/color][color=#dd0000]'view'[/color][/font][font=NSimsun][color=#007700]);
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]allow[/color][color=#007700]([/color][color=#dd0000]'user'[/color][color=#007700], array([/color][color=#dd0000]'Default'[/color][color=#007700], [/color][color=#dd0000]'News'[/color][color=#007700]), array([/color][color=#dd0000]'reply'[/color][color=#007700], [/color][color=#dd0000]'download'[/color][/font][font=NSimsun][color=#007700]));
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]allow[/color][color=#007700]([/color][color=#dd0000]'staff'[/color][color=#007700], array([/color][color=#dd0000]'Default'[/color][color=#007700], [/color][color=#dd0000]'News'[/color][color=#007700]), array([/color][color=#dd0000]'delete'[/color][color=#007700], [/color][color=#dd0000]'update'[/color][/font][font=NSimsun][color=#007700]));
[/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]allow[/color][color=#007700]([/color][color=#dd0000]'admin'[/color][/font][color=#007700][font=NSimsun]);
  
[/font][/color][font=NSimsun][color=#ff8000]//验证权限,如果没有登录则以游客身份登录
[/color][color=#0000bb]$auth [/color][color=#007700]= [/color][color=#0000bb]Zend_Auth[/color][color=#007700]::[/color][color=#0000bb]getInstance[/color][/font][font=NSimsun][color=#007700]();
if(![/color][color=#0000bb]$auth[/color][color=#007700]->[/color][color=#0000bb]hasIdentity[/color][/font][font=NSimsun][color=#007700]())
{
     [/color][color=#0000bb]$auth[/color][color=#007700]->[/color][color=#0000bb]getStorage[/color][color=#007700]()->[/color][color=#0000bb]write[/color][color=#007700]((object)array([/color][color=#dd0000]'username' [/color][color=#007700]=> [/color][color=#dd0000]'Guest'[/color][/font][font=NSimsun][color=#007700],
                                                [/color][color=#dd0000]'role' [/color][color=#007700]=> [/color][color=#dd0000]'guest'[/color][/font][font=NSimsun][color=#007700],
                                                [/color][color=#dd0000]'truename' [/color][color=#007700]=> [/color][color=#dd0000]'游客'[/color][/font][font=NSimsun][color=#007700]));
}
[/color][color=#0000bb]$router [/color][color=#007700]= new [/color][color=#0000bb]Zend_Controller_Router_Rewrite[/color][/font][color=#007700][font=NSimsun]();
[/font][/color][font=NSimsun][color=#ff8000]//$router->addRoute('root',new Zend_Controller_Router_Route('/',array('module' =>'News', 'controller' => 'Index', 'Action' => 'index'))); 也是给出默认控制器的
[/color][color=#0000bb]$front [/color][color=#007700]= [/color][color=#0000bb]Zend_Controller_Front[/color][color=#007700]::[/color][color=#0000bb]getInstance[/color][color=#007700]()->[/color][color=#0000bb]setControllerDirectory[/color][/font][font=NSimsun][color=#007700](array(
                                                                    [/color][color=#dd0000]'default' [/color][color=#007700]=> [/color][color=#dd0000]'./Default/Controllers'[/color][/font][font=NSimsun][color=#007700],
                                                                    [/color][color=#dd0000]'News' [/color][color=#007700]=> [/color][/font][color=#dd0000][font=NSimsun]'./News/Controllers'
                                                                    [/font][/color][font=NSimsun][color=#007700]))
                                              ->[/color][color=#0000bb]setRouter[/color][color=#007700]([/color][color=#0000bb]$router[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]setParam[/color][color=#007700]([/color][color=#dd0000]'Zend_Acl'[/color][color=#007700], [/color][color=#0000bb]$acl[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]setParam[/color][color=#007700]([/color][color=#dd0000]'Zend_Auth'[/color][color=#007700], [/color][color=#0000bb]$auth[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]setBaseUrl[/color][color=#007700]([/color][color=#dd0000]'/zf/index.php'[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]setParam[/color][color=#007700]([/color][color=#dd0000]'noViewRenderer'[/color][color=#007700], [/color][color=#0000bb]true[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]setParam[/color][color=#007700]([/color][color=#dd0000]'useDefaultControllerAlways'[/color][color=#007700],[/color][color=#0000bb]true[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]throwExceptions[/color][color=#007700]([/color][color=#0000bb]true[/color][color=#007700])->[/color][color=#0000bb]returnResponse[/color][color=#007700]([/color][color=#0000bb]false[/color][/font][font=NSimsun][color=#007700])
                                              ->[/color][color=#0000bb]dispatch[/color][/font][font=NSimsun][color=#007700]();
[/color][color=#0000bb]?>[/color] [/font][/color]
[color=#000000][font=新宋体][/font][/color]
[color=#000000][font=新宋体][color=#000000][color=#000000][font=宋体][/font][/color][/color]具体登录内容Zend_Auth操作省略([url=http://hi.baidu.com/zhangsilly/]博客[/url]上有)
[/font][/color]

[[i] 本帖最后由 wps2000 于 2007-6-16 17:32 编辑 [/i]]

2007-6-16 17:05 wps2000
内容长度限制!
接上文:

[color=#000000][font=新宋体]而在Default模块的IndexController中,如下访问访问控制链(./Default/Controllers/IndexController.php)

[color=#000000][color=#000000][font=NSimsun][color=#0000bb]<?php
[/color][color=#007700]class [/color][color=#0000bb]IndexController [/color][color=#007700]extends [/color][/font][color=#0000bb][font=NSimsun]Zend_Controller_Action
[/font][/color][font=NSimsun][color=#007700]{
        public function [/color][color=#0000bb]indexAction[/color][/font][font=NSimsun][color=#007700]()
        {
        [/color][color=#0000bb]$view [/color][color=#007700]= new [/color][color=#0000bb]Zend_View[/color][/font][font=NSimsun][color=#007700];
        [/color][color=#0000bb]$view[/color][color=#007700]->[/color][color=#0000bb]name [/color][color=#007700]= [/color][color=#dd0000]'张心灵'[/color][/font][font=NSimsun][color=#007700];
        [/color][color=#0000bb]$view[/color][color=#007700]->[/color][color=#0000bb]title [/color][color=#007700]= [/color][color=#dd0000]'测试'[/color][/font][font=NSimsun][color=#007700];
        [/color][color=#0000bb]$view[/color][color=#007700]->[/color][color=#0000bb]setScriptPath[/color][color=#007700]([/color][color=#dd0000]'./Default/Views/Index'[/color][/font][font=NSimsun][color=#007700]);
        [/color][color=#0000bb]$view[/color][color=#007700]->[/color][color=#0000bb]addScriptPath[/color][color=#007700]([/color][color=#dd0000]'./Default/Views'[/color][/font][font=NSimsun][color=#007700]);
        [/color][color=#0000bb]$this[/color][color=#007700]->[/color][color=#0000bb]getResponse[/color][color=#007700]()->[/color][color=#0000bb]appendBody[/color][color=#007700]([/color][color=#0000bb]$view[/color][color=#007700]->[/color][color=#0000bb]render[/color][color=#007700]([/color][color=#dd0000]'Index.phtml'[/color][/font][font=NSimsun][color=#007700]));
        }
        public function [/color][color=#0000bb]downloadAction[/color][/font][font=NSimsun][color=#007700]()
        {
        [/color][color=#0000bb]$acl [/color][color=#007700]= [/color][color=#0000bb]$this[/color][color=#007700]->[/color][color=#0000bb]getInvokeArg[/color][color=#007700]([/color][color=#dd0000]'Zend_Acl'[/color][/font][font=NSimsun][color=#007700]);
            if(![/color][color=#0000bb]$acl[/color][color=#007700]->[/color][color=#0000bb]isAllowed[/color][color=#007700]([/color][color=#0000bb]$this[/color][color=#007700]->[/color][color=#0000bb]getInvokeArg[/color][color=#007700]([/color][color=#dd0000]'Zend_Auth'[/color][color=#007700])->[/color][color=#0000bb]getStorage[/color][color=#007700]()->[/color][color=#0000bb]read[/color][color=#007700]()->[/color][color=#0000bb]role[/color][color=#007700], [/color][color=#dd0000]'Default'[/color][color=#007700], [/color][color=#dd0000]'download'[/color][color=#007700])) [/color][color=#0000bb]$this[/color][color=#007700]->[/color][color=#0000bb]getResponse[/color][color=#007700]()->[/color][color=#0000bb]appendBody[/color][color=#007700]([/color][color=#dd0000]'访问不合法'[/color][/font][font=NSimsun][color=#007700]);
            else [/color][color=#0000bb]$this[/color][color=#007700]->[/color][color=#0000bb]getResponse[/color][color=#007700]()->[/color][color=#0000bb]appendBody[/color][color=#007700]([/color][color=#dd0000]'合法访问'[/color][/font][font=NSimsun][color=#007700]);
        }
}[/color] [/font][/color][/color]
[color=#000000]
[/color]
[color=#000000][color=#000000]运行[url=http://localhost/zf/index.php/index/download]http://localhost/zf/index.php/index/download[/url][/color][/color]
[color=#000000][color=#000000]结果一切良好![/color][/color]
[color=#000000][color=#000000]在其他页面中登录之后也如同期望的一样运行了![/color][/color]
[color=#000000]
[/color]
[color=#000000][color=#000000]实际使用中 [font=宋体]您可以将[color=red] 访问不合法那句[/color] 改为 _froward 等等,让用户登录就行了,看起来Zend Framework使用还是蛮方便的(除了Zend_XmlRpc,那么大个Bug,居然这么就了都没修复)[/font][/color][/color]
[color=#000000][color=#000000][font=宋体][/font][/color][/color]
[color=#000000][color=#000000][font=宋体]有空到我空间坐坐![/font][/color][/color]
[/font][/color]

2007-6-16 17:10 wps2000
PS: 用户表:
[align=left][align=left][size=12pt]CREATE TABLE `user` ( [/size][/align][/align][align=left][align=left][size=12pt]`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 ( [/size]
[/align][/align][align=left][align=left][size=12pt]`username` [/size][/align][/align][align=left][align=left][size=12pt])[/size][/align][/align][size=12pt]) ENGINE = MYISAM CHARACTER SET gbk COLLATE gbk_chinese_ci COMMENT = '[/size][size=12pt]用户表[/size][size=12pt]';[/size]


[size=12pt]存储了一个role字段![/size]


[size=12pt]不过有一点,像Discuz的用户组(角色)权限是可以改动的,如果把权限、角色对存入数据库的话,每次执行都查询数据库初始化访问控制链,效率肯定会受影响,如果作为rightConfig.php 存在数组中,那还没试过,貌似也比较麻烦[/size]

2007-6-17 00:10 wps2000
此外,陈老大看看这是什么问题!(在preDispatch中控制权限的)
[code]
<?php
class IndexController extends Zend_Controller_Action
{
        public function preDispatch()
        {
                if(!$this->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 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('合法访问');
        }
}
[/code]
也就是说不合法的用户会被 _forward到 Default的UserController下的loginAction上!
一切看起来都没问题!但是执行的结果是:
Fatal error: [color=Red]Uncaught exception 'Zend_Exception' with message 'File "UserController.php" was not found'[/color] in E:\Program Files\web\zf\Zend\Loader.php:155 Stack trace: #0 E:\Program Files\web\zf\Zend\Loader.php(87): Zend_Loader::loadFile('UserController....', Array, true) #1 E:\Program Files\web\zf\index.php(6): Zend_Loader::loadClass('UserController') #2 [internal function]: __autoload('UserController') #3 E:\Program Files\web\zf\Zend\Controller\Dispatcher\Standard.php(269): class_exists('UserController') #4 E:\Program Files\web\zf\Zend\Controller\Dispatcher\Standard.php(203): Zend_Controller_Dispatcher_Standard->loadClass('UserController') #5 E:\Program Files\web\zf\Zend\Controller\Front.php(889): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #6 E:\Program Files\web\zf\index.php(44): Zend_Controller_Front->dispatch() #7 {main} thrown in E:\Program Files\web\zf\Zend\Loader.php on line 155

而这个UserController绝对放在了Default/Controllers/下面了,而且,同文件夹下有一个 MyController.php的文件,而将_forward改为
_forward('index', 'my', 'Default') 则运行一切正常了!(郁闷)

而且貌似在 preDispatch 中控制权限也太呆板了吧!

PS:[color=Red]请问PHP 开了 magic_quotes_runtime 为 on 之后是不是 pack 或者 unpack 的时候会产生错误?[/color]

2007-10-25 23:10 abin30
ACL的存储 我想这样做:
res,role,rule 都保存在数据库里边,方便管理。同时呢,为了保证效率,可以在每次修改后将这个东西初始化到个一个文件里边。。 整个授权过程,都在这个文件里边完成。
在使用的时候 require 这个文件就可以了吧。。

另外就是。。。  role 可能不会有太多,,但是 res 和rule 可能会根据不同应用变很多。。另外一个想法就是这样。。

1、role 关系还是可以缓存到一个文件共用。2、具体的 res 和对应的rule 信息在用户访问对应模块的时候加载。



另外。。。。。  考虑用户登陆的时候将起可用的授权信息全部读取

[[i] 本帖最后由 abin30 于 2007-10-25 23:21 编辑 [/i]]

页: [1]


Powered by Discuz! Archiver 5.5.0  © 2001-2006 Comsenz Inc.