+ 转载自: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. myeclipse启动项目时报:An internal error occurred during: "Launching TestSpring on Tomcat 7.x". java.lang.NullPointerException 解决方法

    如果出现了上述的错误按照如下的3个步骤解决: 1.首先关闭MyEclipse工作空间. 2.然后删除工作空间下的 “/.metadata/.plugins/org.eclipse.core.runti ...

  2. iOS 静态库中使用宏定义区分iPhone模拟器与真机---备用

    问题描述 一般项目中,可以使用宏定义来判断模拟器还是真机,这无疑是有效的. #if TARGET_IPHONE_SIMULATOR #define SIMULATOR 1 #elif TARGET_O ...

  3. 基于 libpcap库的sniffer程序

    基于 libpcap库的sniffer程序 Libpcap库是WireSharek和Tcpdump抓包程序的基础,利用libcap我们自己也可以实现自己的抓包程序,在网络上实时抓包分析,或者利用处理的 ...

  4. No Hibernate Session bound to thread, and configuration does not allow creat

    No Hibernate Session bound to thread, and configuration does not allow creat 今天遇到这么一个错误,在网上差了很多都没有能解 ...

  5. simhash--文本排重

    转载自 https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/06.12.md http: ...

  6. smarty 比较运算符对照表

    smarty 比较运算符对照表  运算符 中文解释 eq 相等 ne.neq 不相等 gt 大于 lt 小于 gte.ge 大于等于 lte.le 小于等于 not 非 mod 求模 is [not] ...

  7. QLGame 2d Engine源码地址

    QLGame 2d Engine源码地址已经提交到github上,地址为:https://github.com/wsgzxl/QLGame2dEngine

  8. XXX is not in the sudoers file.This incident will be reported

    在fefora 10安装xz解压软件时,sudo make install 时,报错: 原因未知,在网上搜索为:权限问题,解决办法如下(来自百度): 解决方法如下: >.进入超级用户模式.也就是 ...

  9. ANDROID_MARS学习笔记_S05_006_距离传感器

    import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import ...

  10. JavaScript 作用域和变量提升

    本文是这篇文章的简单翻译. 如果按照下面的代码按照JavaScript程序的执行方式执行,alert函数会显示什么? var foo = 1; function bar() { if (!foo) { ...