使用 Zend_Auth 和 Zend_Db 实现用户认证(ZF Study)

<文章大部分内容取自《PHP Web 2.0 》这本书>,最近在学习这本书 ^ ^

来记录一下如何使用 Zend Framework(ZF)来实现用户的认证操作:

首先先来看看 ZF 手册对 Zend_Auth 组件的简介:

Zend_Auth 为认证(authentication)和一些通用用例情景的具体认证适配器提供了一个API。

Zend_Auth 只涉及 认证而不是授权。认证被宽松地定义为基于一些证书(credential)来确定一个实体(例如,身份)是否确实是它所声称的。授权是一个过程,它决定是否允许一个实体对其他实体进行访问、执行操作,它超出了Zend_Auth的范围。更多关于Zend Framework 授权和访问控制的信息,参见 Zend_Acl.

Note: Zend_Auth 类通过它的 getInstance()方法实现 Singleton 模式 - 只有一个实例可用。这意味着使用 new 操作符和 clone 关键字将不能在Zend_Auth 类中工作,而要使用 Zend_Auth::getInstance() 来代替。

1,数据库表信息

在我们的 MySQL 里新建一个 phpweb20 数据库及 users 表,作为测试,建表的 SQL 语句如下所示:

CREATE TABLE `users` (                                    
          `user_id` bigint(20) unsigned NOT NULL auto_increment,  
          `username` varchar(255) NOT NULL,                       
          `password` varchar(32) NOT NULL,                        
          `user_type` varchar(20) NOT NULL,                       
          `ts_created` datetime NOT NULL,                         
          `ts_last_login` datetime default NULL,                  
          PRIMARY KEY  (`user_id`),                               
          UNIQUE KEY `user_id` (`user_id`),                       
          UNIQUE KEY `username` (`username`)                      
        ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=gbk

主键为 user_id 字段。

2,Zend_Auth 如何工作

      首先我们要理解 Zend_Auth 所使用的术语,标识一个用户的唯一信息称为其“身份”,用户成功地认证以后,将其身份存储在一个 PHP 会话之中,从而在以后的页面中能够标识这些用户。(关于这里的 PHP 会话,Zend_Auth 为此提供了一个 Zend_Auth_Storage_Session 类,而这个类又进一步使用了 Zend_Session 组件,这实际上是 PHP 的 $_SESSION 变量的一个包装器,而且提供了更强大的功能)

      要认证一个用户,用户必须提供一个凭证,在我们的例子当中,使用 users 表中的 password 作为用户的凭证,我们将使用一个适配器根据数据库来检查给定的用户的身份和凭证。这个适配器是 Zend_Auth_Adapter_DbTable 适配器,这个适配器设计为使用 Zend_Db 组件,如果要是想编写自己的适配器,只需实现一个方法:authenticate() 方法,该方法要返回一个 Zend_Auth_Result 对象。这个对象包含着认证是否成功的有关信息,还包含一些诊断信息。

3,实例化 Zend_Auth

      Zend_Auth 是一个单例类,使用静态的 getInstance() 方法来获取这个实例,然后必须使用 setStorage() 方法设置存储类(要注意,我们使用的是 PHP 的会话):

以下代码用于建立 Zend_Auth 实例:

$auth = Zend_Auth::getInstance();
$auth -> setStorage(new Zend_Auth_Storage_Session());

4,如何完成认证

来说一些具体的关于 Zend_Auth_Adapter_DbTable 的东西:

      我们将使用 Zend_Auth_Adapter_DbTable 认证适配器,使用这个适配器之前,必须已经有一个合法的 Zend_Db 对象。它的实例化需要 5 个参数:

> 合法的 Zend_Db 对象($db);

> 所用数据库表的名(这里使用的是 users);

> 保存用户身份的列(username 字段);

> 保存用户凭证的列(password 字段);

> 最后一点,对凭证的处理。这实际上是包装凭证的一个函数,假如存储用户信息的时候,password 字段存放的是用户密码的 MD5 散列值,那么我们就要把 md5(?) 作为最后一个参数传入。此问号只是 Zend_Db 在哪里带入口令值。

      一旦实例化了 Zend_Auth_Adapter_DbTable ,就可以设置身份(username)和凭证(password)了,为此要使用 setIdentity() 和 setCredential() 方法。接下来,在 $auth 对象(Zend_Auth 的实例)上调用 authenticate() 方法,而传入 anthenticate() 方法的唯一参数是适配器($adapter),通过它来返回一个 Zend_Auth_Result 的一个实例。还可以通过调用 Zend_Auth_Result 对象的 isValid() 方法来查看用户是否通过了认证,还可以调用其他的方法来查看错误信息。

实现代码如下:

<?php

/**
 * 使用 Zend_Auth 和 Zend_Db 实现用户认证
 */

//启用 ZF 的自动调用机制(必备的一步)
require_once('Zend/Loader/Autoloader.php');
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);

//数据库配置数组
$params = array('host'     => 'localhost',
				'username' => 'root',
				'password' => 'password',
				'dbname'   => 'phpweb20'
				);	

$db = Zend_Db::factory('pdo_mysql', $params);

//初始化 Zend_Auth 组件
$auth = Zend_Auth::getInstance();
$auth -> setStorage(new Zend_Auth_Storage_Session());

//初始化认证适配器
$adapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'username', 'password', 'md5(?)');

//设置身份
$adapter -> setIdentity('fakeUsername');
//设置密码
$adapter -> setCredential('fakePassword');
//验证
$result = $auth -> authenticate($adapter);//返回 Zend_Auth_Result 实例

if($result -> isValid())
{
	//登录成功
	echo "Succeed!";
}
else
{
	//登录失败
	switch($result -> getCode())
	{
		case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
			echo 'Identity not found!';
			break;
		case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
			echo 'Multiple users found with this identity!';
			break;
		case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
			echo 'Invalid password!';
			break;
		default:
			var_dump($result -> getMessages());
	}
}

?>

      其实还可以使用 $auth 对象来检查一个用户是否通过认证。hasIdentity() 方法指示一个用户是否通过认证,为了确定用户的具体身份,可以使用 getIdentity() 方法。类似地,可以使用 clearIdentity() 方法来注销用户,如果使用 PHP 会话作为存储方法,实际上,这会从会话中删除指定用户的身份。

posted @ 2010-11-16 01:00  无墨来点睛  Views(2284)  Comments(1Edit  收藏  举报