Zend framework2 - Zend\Authentication和Zend\Acl 用户身份验证与权限控制-Demo参考OK

[ZF2]Zend Framework 2.0.3 Beta: Zend\Authentication和Zend\Acl的用户身份验证

(2012-05-03 08:54:45)


  1. Demo的文件结构组织

   先介绍下我的Demo的组织方式,方便大家理解(ZF2的文件夹的组织形式我是上网下别人的),其中红色的为本例操作中会修改的文件:

   + MyTest(我的工程文件夹,放在apache2\htdocs目录下)

    |-application(是空文件夹

    |+config

    | | +autoload(里面有global.cofig.php,没涉及到

    | |application.config.php(用于配置modules,路径等参数

    | +module

   | | +Application (这就是一个module,在这个工程里对应的就是首页,可以直接把登陆的写在这里面

   | | +Test (我的登陆是写在这个module里

   | | | +config

   |   | | module.config.php (用来配置module的di等

   |   | +src

   |   | | +Test

   |   |   | +Controller

   |   |   | | AdminController.php这个就是登陆用到的控制器

   |   |   | | TestController.php这个是用来显示登陆后的信息

   |   |   | +Model

   |   | +view (这是存放显示文件,这里就不再展开了

    |+public

   | | +css

   | | +images

   | | +js

   | | .htaccess

   | | index.php (应用程序的入口文件

    |+vendor

     | +ZendFramework

     | | +library

        | +MyTest (放一些插件文件

        | | +Acl

        | | | Navigation.phpAcl进行验证的初始化类,后面会具体讲到

        | | +Controller

        | | | +Plugin

        |   | | Acl.php (Acl插件

        | +Zend (Zend 2.0.3Beta库

   2.Zend\Authentication库

   这个库的作用主要是用于将用户录入的个人信息与数据库进行比较,判断用户是否为已注册用户,从而确定其身份,同时可将登陆的用户信息存入SESSION中(对SESSION不了解的可以上网搜索),用户跳到别的页面中时,其登陆信息依然存在。

   Zend\Authentication库文件的主要目录有:

   + Zend

    |+Authentication

    | +Adapter

     | | DbTable.php

     | +Exception

     | +Storage

     | AuthenticationService.php

     | Result.php

   当然这些可以自己写数据库操作代码实现,但ZF的类能帮助我们更快速、方便地进行开发。 

   使用Authentication进行用户身份验证时,我主要用Adapter\DbTable进行数据库的连接,使用AuthenticationSerivce类和Result类进行验证操作,因此你需要在登陆控制器类中(我这里为AdminController.php)添加如下代码:

    Code2.1. 

   useZend\Authentication\Adapter, //使用命名空间,2.0中新增的功能,方便大型网站的开发

      Zend\Authentication,

      Zend\Authentication\Result;

   然后在AdminController.phploginAction()中加入如下代码:

    Code 2.2.

   ... //获取用户提交的信息,并判断有效性

   if($form->isValid($formData)) //若有效

   {

       // 获取表单的数据

       $adminName = $form->getValue('adminName');   //adminName为用户名表单的name值,即name="adminName"
       $password= $form->getValue('password');    //password为密码表单的name值

       // 通过数据库获取authAdapter,这里的$this->adminTable->getAdapter()是我自定义的函数,主要是输入一个adapter参数,可参考Zend\Db\Adapter获取adapter的方法,这里不再细说了
       $authAdapter= new\Zend\Authentication\Adapter\DbTable($this->adminTable->getAdapter(),
                      'admin',        
// 数据库中存放注册信息的表的名称
                       'admin_name',   // 表中存放用户名的字段
                       'password'    // 表中存放密码的字段

 'md5(?)');     //是否对密码进行MD5编码,这里我没选,直接用明码

    

      // 将用户名和密码进行验证
        $authAdapter->setIdentity($adminName)->setCredential($password);
       $auth = new \Zend\Authentication\AuthenticationService();
       $result =$auth->authenticate($authAdapter);
       if($result->isValid())
       {

            // storing in the session
             $auth->getStorage()->write((object)array('adminName'=> $adminName,
                                                     'password' => $password,

     'role' =>...//这里可保存role值,后面的Acl会用到,role值可存在database文件或.ini文件中

                                            ));

            // 跳转到显示信息页面
            return$this->redirect()->toRoute('default',array('controller' => 'test',
                  'action' => 'index'));
        }
       else
       {

            // 虽然这里我显示了错误信息,但这里面我还不知道如何在VIEW里显示
            switch($result->getCode())
            {
            case Result::FAILURE_IDENTITY_NOT_FOUND:
                $errorMessage = "Admin name isn't exist!";
             break;
            case Result::FAILURE_CREDENTIAL_INVALID:
                $errorMessage = "Your password is wrong!";
            break;
            default:
                 $errorMessage = "There are some mistakes when login!";
             }

              // 停留在注册页,就是这里,需改将参数回传
             return$this->redirect()->toRoute('default',array('controller' => 'admin',
                  'action' => 'login'));
         }

     }

   之后,如果你想知道是否已经登陆,在相应的Action里加上判断即可:

    Code 2.3.

    public functionexampleAction()

    {

       $auth = new AuthenticationService();   //获取实例化Zend\AuthenticationService对象

       if($auth->hasIdentity())    //判断是否登陆,是,则记录登陆信息

       {

            $user =$auth->getIdentity();

       }

    }

   至此,ZendFramework2.0.3中通过Zend\Authentication进行登陆操作的代码结束了,其操作还是比较简单的。

    3.Zend\Acl库实现用户权限的控制

  Zend\Acl的权限控制主要包括角色定义,资源定义以及制作黑白名单几部分,下面是Acl库文件的主要目录:

   + Zend

    |+Acl

    | +Assertion

     | +Exception

     | +Resource

     || GenericResource.php

    | +Role

     || GenericRole.php

    | Acl.php

   接下来就是要为MyTest工程添加角色和资源,方法就是在最上面的目录里的Navigation.php定义一个继承自Acl的类--Navigation:

    Code 3.1.

   // 添加命名空间

   namespace MyTest\Acl;

   use Zend\Acl\Role\GenericRole,

      Zend\Acl\Resource\GenericResource,

      Zend\Acl\Acl;

class Navigation extendsAcl

{

   public function __construct()

   {

      // 添加了三种角色guest, user, admin,如user的父类是guest,因此它继承了guest的所有权限

      $this->addRole(newGenericRole('guest'));

      $this->addRole(new GenericRole('user'),'guest');

      $this->addRole('admin','user'); 

      // 添加资源,这里以'application' module, 'index'controller, 'index' action为例

      $this->addResource(newGenericResource('Application'));

      $this->addResource(newGenericResource('Application.index'),'Application');

      $this->addResource(newGenericResource('Application.index.index'),'Application');

// 以'test'module, 'test' controller为例

      $this->addResource(newGenericResource('aTest'));

      $this->addResource(new GenericResource('Test.test'),'Test');

... 

      // 添加白名单,资源必须与上面的对应

      $this->allow('guest','Application.index.index');

      $this->allow('user','Application.index.index');

      $this->allow('user', 'Test.test');

      $this->allow('admin');   //允许管理员所有权限

   }

}

   之后,你只需要在相应的Action里实例化这个对象,然后进行判断是否被允许访问相应资源即可,比如我是在TestController.phpindexAction()里添加如下代码的:

Code 3.2.

//相应的命名空间

use Zend\Authentication\AuthenticationService,

   Zend\Authentication,

   MyTest\Acl;

// 初始化角色为游客,并获取角色

$role ='guest';

$auth = newAuthenticationService();

if($auth->hasIdentity())

{

   $user =$auth->getIdentity();

   $role = $user->role;   //role值在前面必须存入session中,不然这里会出错

}

$allowed =false;

$acl = new\MyTest\Acl\Navigation();

 

//checking if the roles have right to access

 

if($acl->isAllowed($role,'test', 'index'))

 

{

   

   $allowed = true;

 

}

 

if(!$allowed)

 

{

  

    //返回到登陆页

   

   return$this->redirect()->toRoute('default',array(

                                                                    'controller' =>'admin',

 

                                 'action' =>'login',

));

}

  到这里,Zend\Authentication与Zend\Acl结合的用户身份验证的操作都全部完成了,但有一个的麻烦的地方就是用这里的代码,在判断每个页面是否能被访问时,都需要在相应的Action里添加Code3.3.的判断代码,显然非常地不方便,实际上好像可以用插件实现



阅读更多
个人分类: PHP Zend Framework
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭