+ 转载自: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. Android使用adb工具及root权限完成手机抓包

    1.环境准备/注意: 手机要求已经root. 首先需要配置JDK环境变量,这里主要讲解抓包,JDK环境变量配置跳过. 将包内附带的adb.zip解压到C盘根目录.  整个操作过程都需要用手机用数据线连 ...

  2. arm-linux-gcc编译器测试

    1.#include <>与#include ""的区别 #include <>只在标准库中搜索头文件,而#include ""首先在用 ...

  3. 单片微机原理P0:80C51结构原理

    本来我真的不想让51的东西出现在我的博客上的,因为51这种东西真的太low了,学了最多就所谓的垃圾科创利用一下,但是想一下这门课我也要考试,还是写一点东西顺便放博客上吧. 这一系列主要参考<单片 ...

  4. JAVA实现前几秒几分钟几天前几年源码

    package com.date; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...

  5. Desert King

    poj2728:http://poj.org/problem?id=2728 题意:给你n的点,每一个点会有一个坐标(x,y),然后还有一个z值,现在上你求一棵生成树,是的这棵生成树的所有边的费用/所 ...

  6. 两台CISCO2691测试静态路由汇总,浮动静态路由和负载分担静态路由配置

    Dynagen的配置文件内容: #Lab - autostart = False [localhost] [[]] ram = image = C:\Program Files (x86)\Dynam ...

  7. PorterDuff及Xfermode初识

    图像合成,是将两幅退昂放在一起的动作,它使得我们能够同时看到两幅图像的特征. 我们可以首先在Canvas对象上绘制一个位图对象,然后再相同的Canvas对象上绘制第二个位图对象的方式来实现合成.不过这 ...

  8. php Laravel 框架 介绍及安装

    Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁.富于 ...

  9. USACO3.44Raucous Rockers

    USACO挂了一小时..我坚持不懈的等..终于打开了  把3章最后一题交了 可以安心的睡去了 之前题意没看清楚 不知道要有序 写了一状压 结果TLE了 再优化也TLE 后来想写状态转移时发现 它必须有 ...

  10. MS SQL Server 如何得到执行最耗时的前N条T-SQL语句-

    --得到最耗时的前N条T-SQL语句 --适用于SQL SERVER 2005及其以上版本 --给N赋初值为30 ;with maco as ( select top (@n) plan_handle ...