+ 转载自:Zend Framework 2参考Zend\Authentication(数据库表认证)

介绍

Zend\Authentication\Adapter\DbTable提供对存储在数据库表中的凭据进行验证的能力,因为Zend\Authentication\Adapter\DbTable要求Zend\Db\Adapter\Adapter实例进行构造,每个实例绑定到特定的数据库连接。其他配置选项的设置都可以通过构造器实例的方法处理。
可用的配置选项包括

  • tableName:这是包含身份验证凭据的数据库表的名称,并针对其中的数据库进行认证查询
  • identityColumn:这是用来表示身份数据库表的列的名称。身份列必须包含唯一的值,如用户名或电子邮件地址。
  • credentialColumn:这是用来表示证书数据库表的列的名称。一个简单的身份和密码认证方案,证书的值对应的密码。参看credentialTreatment选项。
  • credentialTreatment:在许多情况下,密码和其他敏感数据加密,哈希,编码,模糊,salted或其他函数或算法进行处理。开发者可以通过任意的SQL指定参数化的字串,像’MD5(?)‘和’PASSWORD(?)‘输入认证数据。由于这些功能具体到底层的RDBMS,请查看数据库手册等功能为你的数据库系统的可用性。

基本用法

正如介绍所说,Zend\Authentication\Adapter\DbTable的构造依赖Zend\Db\Adapter\Adapter实例作为认证适配器实例绑定的数据库连接。首先,应建立数据库连接。
下面的代码创建一个内存中的数据库的适配器,创建一个简单的表schema,并插入一个一行,我们可以稍后执行认证查询。这个例子需要PDO的SQLite扩展可用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use Zend\Db\Adapter\Adapter as DbAdapter;
 
// Create a SQLite database connection
$dbAdapter new DbAdapter(array(
                'driver' => 'Pdo_Sqlite',
                'database' => 'path/to/sqlite.db'
            ));
 
// Build a simple table creation query
$sqlCreate 'CREATE TABLE [users] ('
           '[id] INTEGER  NOT NULL PRIMARY KEY, '
           '[username] VARCHAR(50) UNIQUE NOT NULL, '
           '[password] VARCHAR(32) NULL, '
           '[real_name] VARCHAR(150) NULL)';
 
// Create the authentication credentials table
$dbAdapter->query($sqlCreate);
 
// Build a query to insert a row for which authentication may succeed
$sqlInsert "INSERT INTO users (username, password, real_name) "
           "VALUES ('my_username', 'my_password', 'My Real Name')";
 
// Insert the data
$dbAdapter->query($sqlInsert);

随着数据库连接和表数据已经可用,Zend\Authentication\Adapter\DbTable可以被创建。配置选项的值可以传递给构造函数,setter方法​​可以作为实例化后参数的变动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Zend\Authentication\Adapter\DbTable as AuthAdapter;
 
// Configure the instance with constructor parameters...
$authAdapter new AuthAdapter($dbAdapter,
                               'users',
                               'username',
                               'password'
                               );
 
// ...or configure the instance with setter methods
$authAdapter new AuthAdapter($dbAdapter);
 
$authAdapter
    ->setTableName('users')
    ->setIdentityColumn('username')
    ->setCredentialColumn('password');

除了通过方法getIdentity()返回基于认证结果对象外,通过Zend\Authentication\Adapter\DbTable还可以返回数据表数据确定认证结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Print the identity
echo $result->getIdentity() . "\n\n";
 
// Print the result row
print_r($authAdapter->getResultRowObject());
 
/* Output:
my_username
 
Array
(
    [id] => 1
    [username] => my_username
    [password] => my_password
    [real_name] => My Real Name
)
*/

因为表行里包含证书值,重要的是要防止无意识地访问固定值。

检索结果对象时,我们可以指定哪些列返回,或省略哪些列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$columnsToReturn array(
    'id''username''real_name'
);
print_r($authAdapter->getResultRowObject($columnsToReturn));
 
/* Output:
 
Array
(
   [id] => 1
   [username] => my_username
   [real_name] => My Real Name
)
*/
 
$columnsToOmit array('password');
print_r($authAdapter->getResultRowObject(null, $columnsToOmit);
 
/* Output:
 
Array
(
   [id] => 1
   [username] => my_username
   [real_name] => My Real Name
)
*/

高级用法:持久化一个DbTable的结果对象

默认情况下,Zend\Authentication\Adapter\DbTable对象的身份验证成功后,返回一个认证对象。另一种用途的情况下,开发人员要存储到持久存储机制的Zend\Authentication标识对象包括其他有用信息,解决方法是getResultRowObject()返回一个stdClass对象,下面的代码片段说明了它的用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// authenticate with Zend\Authentication\Adapter\DbTable
$result $this->_auth->authenticate($adapter);
 
if ($result->isValid()) {
    // store the identity as an object where only the username and
    // real_name have been returned
    $storage $this->_auth->getStorage();
    $storage->write($adapter->getResultRowObject(array(
        'username',
        'real_name',
    )));
 
    // store the identity as an object where the password column has
    // been omitted
    $storage->write($adapter->getResultRowObject(
        null,
        'password'
    ));
 
    /* ... */
 
else {
 
    /* ... */
 
}

高级用法范例

虽然Zend\Authentication组件的主要目的(所以Zend\Authentication\Adapter\DbTable)是认证而不是授权,但是基于它们用在哪个域名下,还是有一些实例和问题。根据如何解释你的问题,有时候通过在认证适配器里检查授权问题也许能解决问题。
有了这样的声明的方式,Zend\Authentication\Adapter\DbTable有一些内置的机制,可以利用额外的检查认证时间来解决一些普通的用户问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
use Zend\Authentication\Adapter\DbTable as AuthAdapter;
 
// The status field value of an account is not equal to "compromised"
$adapter new AuthAdapter($db,
                           'users',
                           'username',
                           'password',
                           'MD5(?) AND status != "compromised"'
                           );
 
// The active field value of an account is equal to "TRUE"
$adapter new AuthAdapter($db,
                           'users',
                           'username',
                           'password',
                           'MD5(?) AND active = "TRUE"'
                           );

另外一个场景是免疫机制的实施。免疫是一个术语,指的是一种技术的高度可以提高应用程序的安全。它是基于连接随机字符串到每个密码的想法,使得它不可能完成一个成功的蛮力攻击对数据库使用预先计算好的哈希值从字典。

因此,我们需要修改表来存储我们的免疫字符串:

1
2
3
$sqlAlter "ALTER TABLE [users] "
          "ADD COLUMN [password_salt] "
          "AFTER [password]";

这里有一个简单的方法来为每个用户在注册生成免疫字符串:

1
2
3
4
$dynamicSalt '';
for ($i = 0; $i < 50; $i++) {
    $dynamicSalt .= chr(rand(33, 126));
}

现在让我们来构建适配器:

1
2
3
4
5
6
$adapter new AuthAdapter($db,
                           'users',
                           'username',
                           'password',
                           "MD5(CONCAT('staticSalt', ?, password_salt))"
                          );

注意:通过使用一个静态的免疫硬编码到应用程序中,您可以更好地改善安全。在您的数据库被攻破的情况下(例如SQL注入攻击),但你的数据仍然是是完好的而无法攻击您的Web服务器。

另一种替代方法是在Zend\Authentication\Adapter\DbTable构造完成后使用getDbSelect()方法,

此方法将返回Zend\Db\Sql\Select实例将用于完成常规的authenticate(),重点要注意的是,这种方法将始终返回相同的对象,无论authenticate()是否被调用。因为这些值在authenticate()被放入的选择对象时,这个对象将不会有任何的身份或凭据信息。
下面一个例子可能要使用getDbSelect()方法会检查用户的状态(如果该用户的帐户被启用的情况下)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Continuing with the example from above
$adapter new AuthAdapter($db,
                           'users',
                           'username',
                           'password',
                           'MD5(?)'
                           );
 
// get select object (by reference)
$select $adapter->getDbSelect();
$select->where('active = "TRUE"');
 
// authenticate, this ensures that users.active = TRUE
$adapter->authenticate();

 

Zend Framework 2参考Zend\Authentication(数据库表认证)的更多相关文章

  1. Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍)

    原文:Zend Framework 2参考Zend\Authentication(Zend\Authentication介绍) Zend\Authentication组件提供了认证接口和具体的通用的认 ...

  2. Zend Framework 2参考Zend\Authentication(HTTP认证适配器)

    Zend Framework 2参考Zend\Authentication(HTTP认证适配器) 介绍 Zend\Authentication\Adapter\Http提供了RFC-2617, Bas ...

  3. Zend Framework 2参考Zend\Authentication(摘要式身份验证)

    Zend Framework 2参考Zend\Authentication(摘要式身份验证) 介绍 摘要式身份验证是HTTP身份验证的方法,提高了基本身份验证时提供的方式进行身份验证,而无需在网络上以 ...

  4. 关于Zend Framework 2中 Zend\Session的使用

    一直迷惑于zend\Session的使用,这个是Zend\Session的官方教程的中文版,http://zend-framework-2.yangfan.co/blog/556. 其中最重要的是关于 ...

  5. Zend Framework 1 - Quick Start

    创建 Zend 项目 要创建 Zend 项目,首先要下载并解压 Zend Framework. 安装 Zend Framework 下载最新的 Zend Framework 1.12.20 源码包,( ...

  6. Zend Framework 留言本实战(转)

    一.环境搭建和ZF安装              *[注]本节内容大部分来至Zend Framework官方手册       1.1 Zend Framework下载 Zend Framework 使 ...

  7. 主流PHP框架间的比较(Zend Framework,CakePHP,CodeIgniter,Symfony,ThinkPHP,FleaPHP)

    Zend Framework 优点: Zend Framework大量应用了PHP5中面向对象的新特征:接口.异常.抽象类.SPL等等.这些东西的应用让Zend Framework具有高度的模块化和灵 ...

  8. Zend Framework XML外部实体和安全绕过漏洞

    漏洞版本: Zend Framework 1.x 漏洞描述: Bugtraq ID:66358 Zend Framework是一款开放源代码的PHP5开发框架实现. Zend Framework存在多 ...

  9. Zend Framework学习日记(2)--HelloWorld篇(转)

    Zend Framework学习日记(2)--HelloWorld篇 这一篇主要演示如何用zf命令行工具建立一个基于Zend Framework框架的工程,也是我初学Zend Framework的小练 ...

随机推荐

  1. [转]PHP Session原理分析及使用

    之前在一个叫魔法实验室的博客中看过一篇<php session原理彻底分析>的文章,作者从session的使用角度很好阐述了在代码运行过程中,每个环节的变化以及相关参数的设置及作用.本来想 ...

  2. C语言实现的单链表

    链表是一种线性表,但是并不是顺序存储,而是每个节点里面存储着下一个节点的指针,把存储数据元素的数据串链起来. 单链表的基本实现: typedef int DataType;//定义单链表typedef ...

  3. 开源CMS赏析

    国内CMS产品有很多,开源的产品也不少,大概的可分为以下几类: .NET开源产品:We7CMS: PHP开源产品:Dede CMS.PHP CMS和帝国CMS: ASP开源产品:动易SiteFacto ...

  4. C语言面向对象的简便方法

    都知道C语言是面向过程的,但是现在软件规模越来越大,通过面向对象的方式可以简化开发.业余时间想了个简单的方法,在C中使用一部分面向对象的基本功能.由于C语言自身的限制,并不完善,只能将就用,聊胜于无, ...

  5. [转]HTTP Error 400. The request hostname is invalid.

    一般看到网站提示Bad Request(Invalid Hostname)错误我们都会说是iis,apache出问题了,iis出现这种问题解决办法大概是:IIS> 默认网站> > 属 ...

  6. Python+django部署(一)

    之所以 写这篇文章的原因在于django环境的确轻松搭建,之前Ubuntu上安装了,的确很轻松,但是后期我才知道随便做个环境出来很容易到了后面很麻烦,污 染了系统里的python版本,导致系统pyth ...

  7. ECmall错误:Call to a member function get_users_count() on a non-object

    问题描述: 在后台添加了一个app报错:Call to a member function get_users_count()Fatal error: Call to a member functio ...

  8. [转贴]JAVA :RESTLET开发实例(一)基于JAX-RS的REST服务

    RESTLET介绍 Restlet项目为“建立REST概念与Java类之间的映射”提供了一个轻量级而全面的框架.它可用于实现任何种类的REST式系统,而不仅仅是REST式Web服务. Restlet项 ...

  9. SPRING IN ACTION 第4版笔记-第二章WIRING BEANS-008-在Java配置文件中引入xml配置文件@Import、@ImportResource

    1. package soundsystem; import org.springframework.beans.factory.annotation.Autowired; public class ...

  10. 带圆角的EditText

    转载请注明出处:http://blog.csdn.net/krislight/article 1.定义一个Drawable <?xml version="1.0" encod ...