最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
php中Zend_Auth和Zend_Acl进行登录认证及根据用户角色进行权限控制
时间:2022-06-24 18:11:33 编辑:袖梨 来源:一聚教程网
Zend_Auth_Adapter_Interface中提供了一个接口,我们需要自己去实现
代码如下:
代码如下 | 复制代码 |
require_once 'Zend/Auth/Adapter/Interface.php';
|
解释:在authenticate方法的实现代码中,return一个Zend_Auth_Result对象实例,而查看Zend_Auth_Result的源代码,知道实例化的时候需要传入三个参数:
@param int $code 身份认证的结果(如:Zend_Auth_Result::SUCCESS)
@param mixed $identity 用于身份认证的标示符(如:登录名(张三))
@param array $messages 认证失败的原因数组
而一旦认证成功,则将信息存储到session变量中。
以上的校验工作都是在同一个action中完成的,这里,我使用的是Zend_Auth类中的getCode方法
getCode方法:返回一个zend_auth_resulet常量标识符用来决定认证失败的类型或者是否认证成功(详参:Zend_Auth_Result)
找不到身份表示的错误:Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
无效认证导致的错误: Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
认证成功: Zend_Auth_Result::SUCCESS
一般错误: Zend_Auth_Result::FAILUREZend_Auth中还有其他几个方法:
getStorage方法:
getIdentity():返回认证尝试的身份
isvalid() 返回true表示一个成功的认证尝试
getcode() 返回一个zend_auth_resulet常量标识符用来决定认证失败的类型或者是否认证成功
getIdentity() 返回认证尝试的身份
getmessages() 返回关于认证尝试失败的数组
代码如下 | 复制代码 |
$auth=Zend_Auth::getInstance(); |
实现目标:当发送一个请求(eg:/index.php/shopping/showshop/)的时候,首先应该先进行判断,看是否具有访问权限
用图表示,大概就如下所示:
在action被Zend_Controller_Dispatcher派发之前,会先调用Zend_Controller_Plugin_Abstract类中的preDispatch()方法,因此我们可以继承Zend_Controller_Plugin_Abstract类,在子类中的preDispatch方法中进行权限判断。
代码如下:
代码如下 | 复制代码 |
Verify.php
// $this->_acl->removeAllow($role,$resource); //可以针对某个role移除权限 |
解释:思路其实很简单,首先获取当前用户的角色(或超管或访客),然后使用isAllowed方法来判断请求者在整个 web 应用里是否拥有执行功能的许可,从而执行不同的流程控制。
但是,这里涉及到几个问题:
①preDispatch方法在哪里调用呢
②Verify类在哪里进行实例化
③访问控制列表(acl)如何定义
解答:
第一个问题:preDispatch在Zend_Controller_Action的dispatch方法中被调用(502行左右),该方法先于postDispatch被调用。
第二个问题:在入口文件index.php中进行实例化
$acl = new Acl();//自定义的Acl类
$fc = Zend_Controller_Front::getInstance();//取得Zend_Controller_Front类实例
$fc -> registerPlugin(new Verify($acl));以上代码片段的$acl = new Acl()也正是第三个问题将要回答的
第三个问题:关于访问控制列表的定义,及如何添加角色,添加资源,可以仔细看看官方手册,讲得很详细
http://framework.zend.com/manual/1.12/zh/zend.acl.introduction.html
allow:增加一条“允许”规则到acl列表
如:$acl->allow('guest', null, 'view');//允许游客具有访问的权限
deny:增加一条“禁止”规则到acl列表
如:$acl->deny('guest', null, 'view');//禁止游客具有访问的权限
isAllowed:判断某个角色(role)是否有权访问某个资源(resource)
remove:删除某个资源及其子资源
removeAll:从ACL中删除所有的资源
removeAllow:从ACL中删除某个role有权访问的资源
removeDeny:从ACL中删除某个role禁止访问的资源
removeRole:从ACL中删除某个角色role
addRole:添加一个唯一的角色到ACL注册表中
hasRole:判断某个角色role是否已注册过
getRole:返回当前用户角色
getRoles:返回一个注册角色的数组
getResources:返回注册过的资源数组
在项目中,我们可以写一个Acl类,继承自Zend_Acl,而角色,资源等的添加定义都可以在自定义类中去实现
好比如这样:
Acl.php(自定义)
代码如下 | 复制代码 |
require_once('Zend/Acl.php'); /** * 角色权限控制 * */ class Acl extends Zend_Acl { public function __construct() { $role = $this -> getRole(); //获取用户角色 if ($role=='guest') { //访客角色 $roleGuest=new Zend_Acl_Role('guest'); //创建角色guest $this->addRole($roleGuest); //将角色添加到role注册表 $this -> add(new Zend_Acl_Resource('Login')); $this -> add(new Zend_Acl_Resource('User')); $this -> allow('guest', null, array('login')); //允许访客到登录界面 $this -> allow('guest', null, Array('showuserbydep'));//允许guest根据部门获取用户 }else { //登录用户的权限 //如果该角色不存在,则添加到Role注册表中,否则后面的代码会报错 //eg:Fatal error: Uncaught exception 'Zend_Acl_Role_Registry_Exception' with message 'Role 'admin' not found' if (!$this->hasRole($role)) { $this -> addRole(new Zend_Acl_Role($role)); } //登录的用户都有的权限 $this -> add(new Zend_Acl_Resource('Index')); $this -> add(new Zend_Acl_Resource('Dep')); $this -> add(new Zend_Acl_Resource('Login')); $this -> add(new Zend_Acl_Resource('Order')); $this -> add(new Zend_Acl_Resource('Shopping')); $this -> add(new Zend_Acl_Resource('User')); $this -> add(new Zend_Acl_Resource('Authgroup')); //第三个参数不写,默认具有访问整个控制器的权限 $this -> allow($role,'Index',Array('index')); $this -> allow($role,'Login',Array('index','login','admin','top','left','view','welcome','logout')); $this -> allow($role,'Order',Array('orderhistory')); $this -> allow($role,'Shopping',Array('showmenu','uploadimage','showshop','showfood')); $this -> allow($role,'User','index'); $this -> allow($role,'Dep',Array('showdep')); $this -> allow($role,'Authgroup','index'); $rolePurview = $this -> getRolePurview($role);//角色的权限 //判断权限数据格式是否正确 if(!is_Array($rolePurview)){ echo '权限数据格式有错误!';exit(); }else{ foreach ($rolePurview as $controller => $actionArray){ //controller资源 $resource = ucfirst($controller); //判断是否拥有资源 if(!$this -> has($resource)){//没有资源 $this -> add(new Zend_Acl_Resource($resource));//增加资源 } //判断资源数据格式是否正确 if(!is_Array($actionArray) || empty($actionArray)){ echo '资源数据格式有错误!';exit(); }else{ foreach ($actionArray as $action){ $this -> allow($role, $resource, $action);//允许角色访问资源 } } } } } } /** * 获取用户的角色名 * @return string */ public function getRole() { $ns = Zend_Auth::getInstance() -> getStorage() -> getNamespace(); //有session信息 if(isset($_SESSION[$ns])) {//有登录 if(isset($_SESSION[$ns]['role'])){//判断有没有登录用户的角色信息 $role = $_SESSION[$ns]['role']; }else { $role = 'guest'; } }else { $role = 'guest'; } return $role; } /** * 获得登录用户的数据数据 * */ public function getUserInfo() { $namespace = Zend_Auth::getInstance() -> getStorage() -> getNamespace(); //用户认证失败则返回false if(isset($_SESSION[$namespace]['userInfo'])) { return $_SESSION[$namespace]['userInfo']; }else{ return false; } } /** * 获得权限数据 * @return Array 成功返回 * @return Array 失败返回 * @todo 只有成功登陆页面的情况下才有数据 */ public function getUserPermission() { $namespace = Zend_Auth::getInstance() -> getStorage() -> getNamespace(); if(isset($_SESSION[$namespace]['resourcesPurview'])){ return $_SESSION[$namespace]['resourcesPurview']; }else{ return false; } } /** * 根据角色获取权限(获取指定角色的访问控制列表) * * @param Array $role * @return unknown */ public function getRolePurview($role) { if(!is_string($role)){ return false; }else { $rolePurview = $this -> getAllPurview(); return $rolePurview[$role]; } } /** * 获取所有角色的权限(访问控制列表) * * @return Array */ public function getAllPurview() { $rolePurview = Array(); //判断缓存是否存在,有则从缓存中取,否则从数据库中取 if (!empty($_SESSION['allRolePurviews'])) { $rolePurview = $_SESSION['allRolePurviews']; }else{ $roleDao = Base_Dao_Factory::getObject('Admin_Models_Authgroup'); $result = $roleDao -> getAllGroup(Array('id', 'group_purview')); if(!empty($result)){ foreach ($result as $key => $value){ $purview[$value['id']] = Zend_Json::decode($value['group_purview']); } } $rolePurview = $purview; $_SESSION['allRolePurviews'] = $purview; } return $rolePurview; } } |
解释:自定义的Acl类中,我们首先要判断当前登录用户是访客还是系统用户,从而针对不同的用户角色给予不同的权限。
通过allow()我们可以很容易的针对不同的角色给予不同的权限控制。
注:对于出“访客”外的其他所有用户角色,都有一些默认的权限
现在我抛出一个问题:系统用户肯定有多个分组(比如:超级管理员和普通用户的权限定然不一样)那如何针对不同的用户组分配不同的权限呢?
这个容易,可以将不同组的权限存到数据库中,要用到的时候,根据不同的用户角色查得其所有的访问权限,在循环遍历下,通过allow将角色权限添加到acl中即可,也就是以上的代码片段:
代码如下 | 复制代码 |
//判断资源数据格式是否正确 比如:
[Authgroup] => Array [Order] => Array [Shopping] => Array [User] => Array [System] => Array [Dep] => Array ) ) |
以上是“超级管理员”所拥有的权限
注意一点:在用户登录成功后,可以讲当前用户角色所拥有的权限信息存储到session变量中,这样以后就不必每次都查询数据库去获取了
至于,如何编辑用户组的权限,将其保存到数据库中,可以有多种方法。
相关文章
- 逆水寒手游橙戒流火幻荧什么时候上线 04-25
- 原神仆人阵容搭配推荐 04-25
- 恶意不息铁匠铺怎么升级 04-25
- 原神龙蜥特急斯库拉号成就怎么达成 04-25
- 恶意不息浅滩双子掉落什么 04-25
- 原神仆人阿蕾奇诺武器推荐 04-25